C语言中malloc分配1字节后memset初始化的疑问
代码行为解析
先拆解你的代码逻辑:
char str[] = "";定义的数组仅包含空字符'\0',strlen(str)返回0(strlen统计到第一个'\0'为止,不包含该字符)。- 因此
size = 0 + 1 = 1,malloc(size)只分配了1字节内存。 memset把这1字节填充为'@',所以actual指向的内存中只有一个'@',没有字符串结束符'\0'。
针对你的疑问逐一解释:
为什么能输出"@"?
这是典型的未定义行为。当你用printf("%s", actual)这类方式打印字符串时,函数会从actual指向的地址开始连续读取字节,直到遇到'\0'才停止。你测试的环境中,刚好在分配的1字节内存后面,碰巧存在一个'\0',所以函数停止读取,输出了看起来正常的"@"。但这完全是巧合,换个环境或运行时机,可能会输出乱码、程序崩溃,或者出现其他不可预料的结果。关于2字节的误解
你认为构造"@"需要2字节是对的——合法的C字符串必须以'\0'结尾,所以存储一个字符'@'确实需要2字节(1字节存'@',1字节存'\0')。你的代码没有满足这个条件,只是碰巧没触发错误而已。为什么没报错?
C语言本身不会主动检查这类越界读取的问题,编译器也不一定会发出警告(除非开启严格的编译选项)。未定义行为的特点就是结果不可控,“没报错”绝不代表代码正确。
如果要让代码生成合法的"@"字符串,正确写法示例:
char str[] = ""; // 要存储'@'和结束符,需要2字节 size_t size = 2; char *actual = malloc(size); if (actual != NULL) { actual[0] = '@'; actual[1] = '\0'; }
内容的提问来源于stack exchange,提问作者Barak Tubul
相关产品推荐
相关产品推荐

