Tom*_*ill 0 c memory malloc valgrind heap-memory
我正在学习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;
}
Run Code Online (Sandbox Code Playgroud)
首先,我调用push()
并写入argv[2]
该文件.然后我打电话top()
; 我从malloc得到一块内存,sizeof char,并将它分配给top_element.但是,这应该是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!
}
Run Code Online (Sandbox Code Playgroud)