这是代码,它是C代码.并请说明="字符串"的返回值
char * p = (char*) malloc(sizeof(char) * 100);
p = "hello";
*(p+1) = '1';
printf("%s", p);
free(p);
Run Code Online (Sandbox Code Playgroud)
请注意,p = "hello";不复制任何字符串,只是将指针设置为6字节文字字符串p的地址"hello".复制字符串使用strncpy或strcpy(读取strncpy(3) ...)但是害怕缓冲区溢出.
所以你也是
char * p = malloc(100);
Run Code Online (Sandbox Code Playgroud)
它分配一个能够容纳100个字节的内存区域.让我们假装malloc成功(读取malloc(3) ...)并返回地址0x123456(通常,具体地址不能从一次运行到下一次运行,例如因为ASLR).
然后你分配,p = "hello";所以你忘了地址0x123456(你现在有一个内存泄漏),你p输入6字节文字字符串的地址"hello"(让我们想象它是0x2468a).
后来机器执行的代码*(p+1) = '1';,所以你试图替换e字符(在地址0x2468b)内文字"hello"的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);
Run Code Online (Sandbox Code Playgroud)
并且如果你很幸运(没有内存故障),那么稍后会输出h1llo(输出只有在stdout被刷新时才会发生,因为它被缓冲,例如稍后调用fflush).所以不要忘记打电话
fflush(NULL);
Run Code Online (Sandbox Code Playgroud)
一般建议是阅读您正在使用的每个函数的文档(甚至printf(3) ...).
关于printf和相关的函数,因为stdout通常是行缓冲的,实际上我强烈建议在代码中用\n-eg 结束每个格式控制字符串printf("%s\n", p);; 如果你不这样做(有些情况下你不想......)三思而后行,也许会评论你的代码.
不要忘记编译所有警告和调试信息(例如gcc -Wall -Wextra -g)然后学习如何使用调试器(例如gdb)
| 归档时间: |
|
| 查看次数: |
80 次 |
| 最近记录: |