【问题标题】:Dynamic Memory Deallocation in CC中的动态内存释放
【发布时间】:2014-10-29 14:38:04
【问题描述】:

我有这 2 个结构和 4 个常量:

#define MAX_BLK 16
#define MAX_STR 32
#define C_TRUE  1
#define C_FALSE 0

typedef struct {
  int  rsv;
  void *addr;
  int   size;
  char  tag[MAX_STR];
} BlockType;

typedef struct {
  int numBlocks;
  BlockType *blocks;
} HeapType;

这是我初始化堆结构的函数:

void mh_init(HeapType *heap) {
  heap->numBlocks = 0;
  heap->blocks = (BlockType *) malloc(sizeof(BlockType[MAX_BLK]));
}

这是我分配新块的函数(创建一个 n 字节的块,将新块和信息添加到 heap->blocks 数组,然后返回新内存块的指针):

void *mh_alloc(HeapType *heap, int n, char *label) {
  void *newAddr = (void*) malloc(n);
  heap->blocks[heap->numBlocks].addr = newAddr;
  heap->blocks[heap->numBlocks].rsv = C_TRUE;
  heap->blocks[heap->numBlocks].size = n;
  strcpy(heap->blocks[heap->numBlocks].tag, label);
  heap->numBlocks += 1;
  return newAddr;
}

最后,释放每个块和堆结构:

void mh_cleanup(HeapType *heap) {
  for (int i = 0; i < heap->numBlocks; i++) {
    printf("block %d\n", i);
    free_block(&heap->blocks[i]);
  }
  free(&heap->numBlocks);
  free(heap->blocks);
}

void free_block(BlockType *block) {
  free(&(block->rsv));
  printf(" freed: rsv,");
  if (block->addr != NULL) { free(block->addr);  }
  printf("adr, ");
  free(&(block->size));
  printf("size, ");
  free(block->tag);
  printf("tag\n");
}

一切编译正常,但是当我运行时,我不断收到 glibc 错误:“* glibc detected * ./a3: free(): invalid pointer: 0x002b6470 ***”

我已经进行了一个小时左右的研究,并认为这个错误意味着我将无效地址传递给 free()。基本上它打印出块 0,释放 rsv,但没有别的。谁能告诉我我的方法哪里出了问题?

***注意我的程序还有其他部分,但认为它们对这个问题并不重要

【问题讨论】:

  • 在这种情况下,您可以使用调试器或类似 valgrind 的工具来查看执行过程中发生无效释放的位置和时间。
  • Valgrind 只告诉我 free() 错误发生的方法,但没有什么帮助。几个小时以来,我一直试图找出问题出在哪里,反正对我来说并不明显
  • 好的,然后尝试调试器(例如gdb),当发生无效释放时,您可以看到整个调用堆栈,您尝试释放的指针的值等。
  • Don't cast the return value of malloc() in C。将 to void * 转换成 void * 对我来说是新的,甚至!不要这样做。 :)
  • 我看了一眼,看到了free(&amp;heap-&gt;numBlocks);free(heap-&gt;blocks);。这意味着什么?我很确定你不想那样做。

标签: c memory-management glibc


【解决方案1】:

这看起来很可疑:

  free(&(block->rsv));

您应该只传递从malloc 获得的指向free 的指针。在这种情况下,您在分配的结构中传递了一个指向int 的指针。如果您在分配的数组中的第二个结构上进行操作,那么这肯定不是您从 malloc 获得的指针。如果它是第一个元素,如果这与指向数组的指针相同(不确定是否保证),则可能会释放整个数组,在这种情况下,函数的其余部分在free'd 内存上运行,这很糟糕。

【讨论】:

  • free(&amp;heap-&gt;numBlocks); 也是。在这种情况下可能会发生 coredump。
猜你喜欢
  • 1970-01-01
  • 2013-11-22
  • 2023-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-13
  • 1970-01-01
相关资源
最近更新 更多