【发布时间】:2019-06-13 05:18:47
【问题描述】:
我编写了一些代码来查看malloc() 和memset() 的行为,我发现了一个我不知道发生了什么的情况。
我使用malloc() 为字符数组分配了 15 字节的内存,并且我
想看看如果我错误地使用 memset() 在我创建的指针中设置 100 字节的内存会发生什么。我希望看到 memset() 设置了 15 个字节(并且可能会丢弃一些其他内存)。我在运行程序时看到的是它为我编码的字符设置了 26 字节的内存。
知道为什么要为我创建的指针分配 26 个字节吗?我正在使用 gcc 和 glibc 进行编译。代码如下:
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#define ARRLEN 14
int main(void) {
/* + 1 for the null terminator */
char *charptr = malloc((sizeof(*charptr) * ARRLEN) + 1);
if (!charptr)
exit(EXIT_FAILURE);
memset(charptr, '\0', (sizeof(*charptr) * ARRLEN) + 1);
/* here's the intentionally incorrect call to memset() */
memset(charptr, 'a', 100);
printf("sizeof(char) ------ %ld\n", sizeof(char));
printf("sizeof(charptr) --- %ld\n", sizeof(charptr));
printf("sizeof(*charptr) --- %ld\n", sizeof(*charptr));
printf("sizeof(&charptr) --- %ld\n", sizeof(&charptr));
printf("strlen(charptr) --- %ld\n", strlen(charptr));
printf("charptr string ---- >>%s<<\n", charptr);
free(charptr);
return 0;
}
这是我得到的输出:
sizeof(char) ------ 1
sizeof(charptr) --- 8
sizeof(*charptr) --- 1
sizeof(&charptr) --- 8
strlen(charptr) --- 26
charptr string ---- >>aaaaaaaaaaaaaaaaaaaaaaaa<<
【问题讨论】:
-
你正在导致未定义的行为,所以任何事情都可能发生。
-
知道为什么要为我创建的指针分配 26 个字节吗? 未定义的行为是未定义的。可能有什么东西将新数据写入了你用狂野
memset()破坏的内存。 -
较早的
printf()调用之一可能将零写入了它自己的堆变量之一,而这些变量恰好位于您分配的字符串之后的 11 个字节处。 -
有趣的是,我看到的是一样的,但只是禁用了优化;打开优化会在编译时(令人印象深刻的工作gcc!)警告潜在的缓冲区溢出,并在运行时令人满意地崩溃。
-
#include <unistd.h>是不必要的。您不使用该标题中的任何内容。