【问题标题】:Weird C stack memory overrides奇怪的 C 堆栈内存覆盖
【发布时间】:2023-03-21 00:15:01
【问题描述】:

我正在实现一个 malloc 版本并且可以免费练习。所以,我有一个固定长度(10000)的静态字符数组。然后,我实现了一个 struct memblock 来保存块大小等信息,如果它是空闲的......

我实现 malloc 的方式是将小块(

这是我的代码:

#define MEMSIZE 10000 // this is the maximum size of the char * array
#define BLOCKSIZE sizeof(memblock) // size of the memblock struct

static char memory[MEMSIZE]; // array to store all the memory
static int init; // checks if memory is initialized
static memblock root; // general ptr that deals with both smallroot and bigroot
static memblock smallroot, bigroot; // pointers to storage of small memory blocks and bigger blocks


void initRoots(size_t size, char* fileName, int lineNum)
{
  smallroot = (memblock)memory;
  smallroot->prev = smallroot->next = 0;
  smallroot->size = MEMSIZE - 2 * BLOCKSIZE;
  smallroot->isFree = 1;
  smallroot->file = fileName;
  smallroot->lineNum = lineNum;

  bigroot = (memblock)(((char *)memory) + MEMSIZE - BLOCKSIZE - 1);
  bigroot->prev = bigroot->next = 0;
  bigroot->size = MEMSIZE - 2 * BLOCKSIZE;
  bigroot->isFree = 1;
  bigroot->file = fileName;
  bigroot->lineNum = lineNum;
  init = 1;
}

我使用 GDB 来查看我在哪里遇到了 Seg Fault。它发生在 bigroot->next = 0;被执行。这以某种方式将 smallroot 设置为 0。更奇怪的是什么?如果我设置 bigroot->next = 0x123,那么 smallroot 变为 0x1。如果我设置 0x1234,那么它就变成了 0x12。它将 smallroot 设置为 bigroot->next 的值,不包括其最后两位。我真的不明白这是怎么回事!

这是memblock的定义:

typedef struct memblock_* memblock;

struct memblock_ {
  struct memblock_ *prev, *next;  // pointers to next and previous blocks
  /* size: size of allocated memory
    isFree: 0 if not free, 1 if free
    lineNum: line number of user's file where malloc was invoked
  */
  size_t size, isFree, lineNum;
  char* file; // user's file name where the block was malloced
};

【问题讨论】:

  • 您的意思是最后 2 个半字节或最后一个字节。不是最后 2 位。
  • 能否请您添加memblock的定义,否则很难判断。
  • 你真的应该关心对齐。
  • 对齐是什么意思?如果有人想要整个源,我可以发布一个链接。我真的不明白为什么会这样。

标签: c++ c memory gdb


【解决方案1】:

#define BLOCKSIZE sizeof(memblock) // size of the memblock struct

你想要:

#define BLOCKSIZE sizeof(*memblock) // size of the memblock_ struct

这里的-1 也是假的(创建未对齐的指针):

bigroot = (memblock)(((char *)memory) + MEMSIZE - BLOCKSIZE - 1);

实际上,我将指向内存块的指针存储在内存数组中。 memblock 的值存储在堆栈中。

不,他们不是。 smallrootbigroot 显然指向数组本身。

【讨论】:

  • 实际上,我不想这样做,因为我只想将指向 memblock 的指针存储在 char 数组(“内存”)上。那将指向堆栈中的实际结构。您的方式会占用数组的大量空间(它只有 10000 个字节)。而smallroot和bigroot是类型指针(struct memblock_ *)
  • @1729 如果您想将struct memblock_s 存储在其他地方,您可以这样做。但这不是你的代码当前所做的,正如 AnT 已经告诉你的那样,这是你(当前)问题的根源。
  • 我想过将struct memblock_ 单独存储在一个链表中。我认为静态变量可以做到这一点。但是,有什么办法可以实现,因为我应该实现 malloc?我不能使用 malloc 来制作链表。
猜你喜欢
  • 2015-09-22
  • 2015-03-01
  • 2010-10-14
  • 2012-04-02
  • 2012-02-14
  • 1970-01-01
  • 2013-05-28
  • 2014-04-06
  • 1970-01-01
相关资源
最近更新 更多