我用malloc()和字符串得到一个简单的,意外的结果。 代码:
int main(void) {
char* b64str;
char* binStr = "00000101";
printf("Expected size of allocated structure (b64str): 8\n");
b64str = (char*)malloc((strlen(binStr)+1)*sizeof(char));
printf("Actual size of allocated structure (b64str): %d\n\n", strlen(b64str));
输出:
Expected size of allocated structure (b64str): 8
Actual size of allocated structure (b64str): 0
为什么?
答案 0 :(得分:4)
您为b64str
分配了空间,但该空间未初始化。试图在该缓冲区上调用strlen
会调用undefined behavior。在您的特定情况下,第一个字节恰好设置为0,但您不能依赖该行为。
您无法通过查看分配多少内存。你需要自己跟踪它。
如果要查看分配是否失败,请检查返回的指针是否为NULL
。
b64str = (char*)malloc((strlen(binStr)+1)*sizeof(char));
if (b64str == NULL) {
perror("malloc failed");
exit(1);
}
答案 1 :(得分:2)
strlen()
报告字符串的长度,而不是与分配相关联的内存量。
strlen
函数返回终止空字符前面的字符数。 C11dr§7.24.6.33
考虑改变OP代码。
char* binStr = "00000101";
printf("Result of strlen(binStr) %d\n", (int) strlen(binStr));
// Expect 8 to be printed.
char* b64str = (char*)malloc((strlen(binStr)+1)*sizeof(char));
strcpy(b64str, "123");
printf("Result of strlen(b64str) %d\n", (int) strlen(b64str));
// Expect 3 to be printed.
strcpy(b64str, "12345");
printf("Result of strlen(b64str) %d\n", (int) strlen(b64str));
// Expect 5 to be printed.
这些都没有打印出9的分配大小。请注意,b64str
指向的已分配内存量即使在strcpy(b64str, "123");
size_t sz = strlen(binStr)+1)*sizeof(char);
printf("Allocation size %d\n", (int) sz);
// Expect 9 to be printed.
没有标准方法可以确定与NULL
返回的非malloc()
指针关联的内存量。
malloc
没有为char*
(OP)分配内存
代码未检查malloc()
的返回值以了解分配是否成功。进行NULL
检查。如果代码收到非NULL
,则分配成功。当大小请求为0时,返回值NULL
也可以,但这不是strlen(binStr)+1
的问题。
malloc函数返回空指针或指向已分配空间的指针。 §7.22.3.42
char* b64str = malloc(strlen(binStr)+1);
if (b64str == NULL) {
perror("OOM"); exit(-1);
}
注意:
投标不需要malloc()
返回
sizeof(char)
总是1.
强大的代码检查分配结果
char* b64str = malloc(strlen(binStr)+1);
if (b64str == NULL) { perror("OOM"); exit(-1); }
使用"%zu"
匹配从size_t
strlen()
类型
printf("Result of strlen() %zu\n", strlen(b64str));
答案 2 :(得分:0)
strlen()
在字符串中搜索NUL终止符。它不告诉你为该字符串分配的缓冲区的大小! (只有偶然的第一个字节为零;其他运行可能会产生不同的结果。)
所以你必须自己存储缓冲区的大小,如果这是你想要的。如果您想查看是否已分配任何内存,请检查b64str
本身是否为NULL
。