我正在学习 C,我想知道为什么下面的代码没有崩溃,我只是使用 Valgrind 才发现这个问题。
void push(char *element){
FILE *file = fopen("stack.db", "w");
int rc = fwrite(element, sizeof(element), 1, file);
if (file) fclose(file);
}
void top() {
char *top_element = malloc(sizeof(char));
FILE *file = fopen("stack.db", "r+");
int rc = fread(top_element, sizeof(char), 1, file);
printf("Top element: %s", top_element);
}
int main(int argc, char *argv[]) {
char action = argv[1][0];
switch (action) {
case 'p':
printf("pushing element to stack\n");
push(argv[2]);
break;
case 't':
top();
break;
default:
printf("die\n");
}
return 0;
}
首先我调用push()
并将argv[2]
写入文件。然后我调用 top()
;我从malloc得到一 block 内存,sizeof char,分配给top_element。但是,这应该是 sizeof char*,所以我实际上调用了 malloc(1)
,而我本应该调用 malloc(8)
。此代码有效,我只在使用 Valgrind 时才发现错误。
我的问题是,当我分配给 top_element
的内存大小太小时,它如何工作?
最佳答案
不对,应该是sizeof(char)
。您需要一段足够长的内存来存储单个字符; malloc(sizeof(char))
返回一个指向它的指针。 malloc(sizeof(char*))
将返回一个指向足够内存的指针来存储 char*
。您可以将 malloc(T * n)
视为将 T*
返回给 n
T
。
我怀疑 Valgrind 提示 printf
将读取超出 char* top_element
所表示的字符串的末尾 ,因为它是不是零终止。如果你想从文件中读取一个 n
字节的字符串,你确实需要 n + 1
字节的内存,因为你需要考虑 \0
你应该放在最后。然而,并不是所有的 char*
都代表字符串,所以在很多情况下这种用法是可以的。在你的情况下,它真的应该是:
// Allocate zeroed memory
char *top_element = calloc(2, sizeof(char));
if (top_element)
{
FILE *file = fopen("stack.db", "r+");
int rc = fread(top_element, sizeof(char), 1, file);
printf("Top element: %s", top_element);
free(top_element);
}
else
{
// Out of memory!
}
关于c - 当我 malloc 错误的内存量时,为什么 C 不会崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21628674/