行为为wierd的malloced字符串的赋值

行为为wierd的malloced字符串的赋值,c,C,这是代码,是C代码。请解释=“string”的返回值 请注意p=“hello”不复制任何字符串,只是将指针p设置为6字节文字字符串的地址“hello”。要复制字符串,请使用strncpy或strcpy(读取…),但要害怕 你也是 char * p = malloc(100); 它分配了一个能够容纳100字节的内存区域。让我们假设malloc成功(读取…),并返回了地址0x123456(通常,该具体地址在一次运行到下一次运行时是不可复制的,例如,由于) 然后分配p=“hello”所以您忘记了地

这是代码,是C代码。请解释=“string”的返回值

请注意
p=“hello”
不复制任何字符串,只是将指针
p
设置为6字节文字字符串的地址
“hello”
。要复制字符串,请使用
strncpy
strcpy
(读取…),但要害怕

你也是

 char * p = malloc(100);
它分配了一个能够容纳100字节的内存区域。让我们假设
malloc
成功(读取…),并返回了地址0x123456(通常,该具体地址在一次运行到下一次运行时是不可复制的,例如,由于)

然后分配
p=“hello”
所以您忘记了地址0x123456(现在您有了a),您输入了6字节文本字符串的地址(假设它是0x2468a)

之后,机器执行
*(p+1)=“1”的代码
因此,您试图将literal
中的
e
字符(地址0x2468b)替换为
1
。您会得到一个(或其他),因为该文本字符串位于恒定的只读内存中(例如,至少在Linux上,您的可执行文件的)

更好的代码可能是:

 #define MY_BUFFER_LEN 100
 char *p = malloc(MY_BUFFER_LEN);
 if (!p) { perror("malloc for p"); exit(EXIT_FAILURE); };
 strncpy(p, "hello", MY_BUFFER_LEN); /// you could do strcpy(p, "hello")
 *(p+1) = '1';
 printf("%s", p);
 free(p);
如果幸运的话(没有内存故障),以后会输出
h1llo
(只有当
stdout
被刷新时,才会发生输出,因为它被刷新了,例如,通过稍后调用
fflush
)。所以别忘了打电话

 fflush(NULL);
在上一个代码块之后。读

一般建议是阅读您正在使用的每个函数(甚至…)

关于
printf
和相关函数,由于
stdout
通常是,在实践中,我强烈建议用
\n
结束每个格式控制字符串-例如
printf(“%s\n”,p)在您的代码中;当您不这样做时(在某些情况下,您不想……),请三思而后行,并可能对代码进行注释


不要忘记使用所有警告和调试信息(例如,
gcc-Wall-Wextra-g
)进行编译,然后学习如何使用调试器(例如,
gdb

您的代码不会做您认为它会做的事情

“hello”在幕后是指向六个字符的静态数组的指针,很可能是写保护的

当您将其分配给p时,malloc返回的指针将丢失,而p现在包含一个指向六个字符的静态数组的指针

p+1的分配可能会崩溃,也可能不会崩溃,但无论它做什么,它都是未定义的行为,并将导致故障

free(p)尝试释放六个字符的静态数组。那是行不通的。同样,未定义的行为,如果幸运的话,会立即崩溃

1)在C中,对malloc()的返回进行强制转换是不正确的(C++,可以强制转换)
2) 一旦分配了内存,将值分配给
p
不是由
=
完成的
strcpy(p,“你好”);更好。
3) 一旦分配正确,使用strcpy()
,*(p+1)='1'与p[1]='1'相同,并将导致“h1llo”


顺便说一下,在使用p=“hello”分配值hello(而不是
strcpy()
)之后使用行*(p+1)=“1”将导致问题,如@gnasher、@Basile和其他人所述。

几乎每一行都有问题:
1) 在第一行中,您将为
p
分配新分配内存的地址。哪个是可以的
2) 在下一行中,您将使用某个静态字符串的地址覆盖它。这是不好的,因为分配的内存“丢失”,从而导致内存泄漏。
3) 在第三行中,您试图覆盖静态字符串位置中的某些内容,这可能是只读的,这是错误的

4) 在最后一行中,您试图释放字符串位置的内存,这是内存冲突。

您需要了解指针是什么

在C语言中,没有可以存储字符串的变量。相反,字符串存储在字符数组中。为了能够处理这样的数组,可以使用一个变量(称为指针),该变量存储数组第一个元素的内存地址。此外,字符串有一个特殊的字符(nul字符)来指示它们的结束位置,但这在这里并不相关

在您发布的代码中,您分配内存来存储100个字符(通常为100字节),并获取指向该内存区域的第一个元素p(用于进一步读取:)的指针

无论何时使用字符串文字,都会分配一些内存并将其存储在该内存区域中。当您将其分配给p时,p现在指向新内存区域的第一个元素,该元素存储字符串(因此您丢失了分配给malloc->memory leak的内存)。现在,您尝试修改p指向的字符串。这不起作用,因为字符串文本存储为常量字符串。然后,你尝试释放这个字符串的内存,这是不可能的。所有这些错误都会产生运行时错误,并且不容易检测和修复。为了能够实现所需,请使用strcpy之类的函数将字符串从只读内存区域复制到指针:

strcpy(p, "string");

C中的字符串是数组,不能使用=给数组赋值,只能给数组的索引元素赋值。要复制字符串数据,请使用
strcpy()
strncpy()
。您的代码可能如下所示:

char *p = (char*) malloc(sizeof(char) * 100);
strcpy(p, "hello");   
*(p+1) = '1';
printf("%s", p);
free(p);
试试看。不同之处在于
p=“hello”
会将指针p设置为指向常量字符串“hello”,覆盖指向刚才分配的100字节内存块的指针。
free(p)调用将失败,因为您正在传递分配函数未返回的指针,即使您使用的系统在尝试修改常量数据时未给出写入错误

如果确实需要将指针指向常量字符串(这种情况经常发生),请确保将指针声明为<
char *p = (char*) malloc(sizeof(char) * 100);
strcpy(p, "hello");   
*(p+1) = '1';
printf("%s", p);
free(p);