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