1

在这里,我动态地为 p 分配内存,以便我可以更改字符串的特定字符,但是这段代码挂在中间

 int main()
 {
  char *p;
  p=malloc(10*sizeof(char));
  p="string";
  p[0]='d';
  printf("%s",p);
 }

我尝试p="string"在第 5 行替换,strcpy(p, "string")并且代码运行良好。谁能告诉我这背后的原因。

 int main()
 {
   char *p;
   p=malloc(10*sizeof(char));
   strcpy(p, "string");
   p[0]='d';
   printf("%s",p);
 }
4

5 回答 5

2

指针可以拥有资源 (malloc) 或指向已由另一个实体拥有的资源。当你这样做时p="string";,你正在创建一个const char *你分配字符指针的对象p,通过在前一行中泄漏 malloc'd 内存,在后者中,你只是替换 malloc'd 内存中的内容;前者是错误/问题,后者不是。需要注意的是,虽然泄漏资源/内存是不好的做法,但这不是挂起的原因。

您遇到问题的原因是您在 C 代码中所做的编辑试图编辑您是程序的只读内存空间(const char *变量在程序内存的这一部分中创建为不可变的字节数组)。c++ 何时分配/解除分配字符串文字对此进行了进一步解释。

至于将所需的字节传递给malloc,避免在表达式中使用 type 的好习惯:

const size_t count_required = 10;
char *p = malloc(sizeof(*p) * count_required);
// changing p's type to int* would also work without editing the malloc argument

当 p 的类型更改为,例如floatint或任何其他类型时,表达式将继续正常工作而无需任何更改。

于 2013-01-31T16:58:56.390 回答
1

线

 p="string";

更改p为指向只读字符串文字,从而泄漏进程中先前分配的内存。您不能写入字符串文字,因此p[0]='d';可能会导致段错误。

你的第二个版本,使用

strcpy(p, "string");

将只读字符串文字的内容复制到您之前分配的内存中。您仍在使用您在此处动态分配的缓冲区,因此可以安全地在以后的代码中更改其内容。

另一个非常小的点,sizeof(char)保证为 1,因此您可以简化malloc

 p=malloc(10);
于 2013-01-31T16:57:48.557 回答
1

在 C 中,字符串不是值。不能使用赋值 ( =) 复制字符串,但可以分配指针(指针是“真实”值)。

要将字符串复制到新分配的内存中,您需要:

strcpy(p, "string");

您编写它的方式是malloc()用静态字符串常量的地址覆盖返回的指针。这会导致内存泄漏;避免它们是使 C 成为一种有价值的编程语言的挑战之一。

于 2013-01-31T17:00:08.053 回答
0

首先,您的第一个程序中存在内存泄漏。然后malloc将指针分配给另一个常量字符串。

其次,在第一个程序中,您正在修改一个 CONSTANT 字符串。但是第二个“正确”程序,您正在复制该常量字符串并将其复制到分配的内存中。哪个,你可以自由改变。

于 2013-01-31T16:59:54.383 回答
0

char amessage[] = "now is the time"; /* an array */

char *pmessage = "now is the time"; /* a pointer */

"amessage是一个数组,大到足以容纳字符序列并'\0'对其进行初始化。数组中的各个字符可能会更改,但消息将始终引用相同的存储。另一方面,pmessage是一个指针,初始化为指向一个字符串常量;该指针随后可能会被修改为指向别处,但如果您尝试修改字符串内容,则结果未定义。”

礼貌K&R

于 2013-01-31T17:05:33.377 回答