当我malloc错误的内存量时,为什么C不崩溃

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太小时,它是如何工作的?

Ada*_*ght 7

不,它应该是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)

  • 此外还有内存泄漏,因为top_element永远不会被释放 (3认同)