为什么当我错误地分配内存量时 C 不会崩溃



我正在学习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 stackn");
push(argv[2]);
break;
case 't':
top();
break;
default:
printf("dien");
}
return 0;
}

首先,我调用push()并将argv[2]写入该文件。然后我呼叫top();我从malloc中获得一块内存,大小为char,并将其分配给top_element。然而,这应该是char*的大小,所以我实际上是在调用malloc(1),而我本应该调用malloc(8)。这个代码有效,我只是在使用Valgrind时才发现错误。

我的问题是,当我分配给top_element的内存太小时,它是如何工作的?

否,应该是sizeof(char)。你想要一段足够长的内存来存储一个字符;malloc(sizeof(char))返回一个指针。则CCD_ 9将返回指向足以存储CCD_。您可以将malloc(T * n)视为将T*返回给nTs。

我怀疑Valgrind在抱怨printf将读取超出由char* top_element表示的字符串的末尾,因为它不是零终止的。如果你想从文件中读取一个n字节的字符串,你确实需要n + 1字节的内存,因为你需要考虑应该放在末尾的。但是,并不是所有的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!
}

您似乎对char *char感到困惑:
char可以包含字符(duh!),而char *是指向字符的指针。指向字符的指针也可以是字符串,但没有是由空字节终止的连续char秒数。

char*top_element=malloc(sizeof(char));

malloc()请求内存以存储单个char,而不是字符串。

printf("顶部元素:%s",Top_element);

告诉printf()需要一个字符串
由于top_element实际上只是一个char,所以它不需要以null终止。如果不是,printf()将读取超过分配,这是未定义的行为(如果幸运的话,printf()将触及未分配页面的页面边界,导致页面错误)。您没有崩溃的原因是未初始化的内存通常包含零字节,这将类似于printf()的null终止符。然而,这并不能保证,依赖它将是非常危险的。

相关内容

  • 没有找到相关文章

最新更新