这是代码,是C代码。请解释“string”的返回值
char * p = (char*) malloc(sizeof(char) * 100);
p = "hello";
*(p+1) = '1';
printf("%s", p);
free(p);
最佳答案
请注意,p = "hello";
不会复制任何字符串,而只是将指针 p
设置为该地址的地址 6 字节文字字符串 "hello"
。要复制字符串,请使用 strncpy
或 strcpy
(读取 strncpy(3) ...),但要害怕 buffer overflows 。
所以你会的
char * p = malloc(100);
分配一个能够容纳100字节的内存区域。让我们假设 malloc
成功(读取 malloc(3) ...)并返回地址 0x123456(通常,该具体地址在一次运行到下一次运行之间无法重现,例如由于 ASLR )。
然后你分配了 p = "hello";
所以你忘记了地址 0x123456 (你现在有一个 memory leak ),然后你输入了 p
地址6 字节文字字符串 "hello"
(假设它是 0x2468a)。
稍后机器执行 *(p+1) = '1';
的代码,因此您尝试替换其中的 e
字符(位于地址 0x2468b) 1
的文字 "hello"
。你会得到一个 segmentation violation (或其他一些 undefined behavior ),因为该文字字符串位于常量只读内存中(例如可执行文件的 text segment ,至少在 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
刷新时才会发生输出因为它是 buffered ,例如通过稍后调用 fflush )。所以别忘了打电话
fflush(NULL);
在上一个代码块之后。阅读 perror(3) 、 fflush(3) 。
一般建议是阅读您正在使用的每个函数的 documentation(甚至 printf(3) ...)。
关于 printf
及相关函数,由于 stdout
通常是 line buffered ,在实践中我强烈建议以 \n
结束每个格式控制字符串-例如。 printf("%s\n", p);
在您的代码中;当您不这样做时(在某些情况下您不想...)请三思而后行,也许可以评论您的代码。
不要忘记使用所有警告和调试信息进行编译(例如 gcc -Wall -Wextra -g
),然后学习如何使用调试器(例如 gdb
)
关于c - 对 malloc 字符串的赋值表现得很奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28752828/