c++ - 奇怪的 C 堆栈内存覆盖

标签 c++ c memory gdb

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

我实现 malloc 的方式是将小块(< 8 字节)放在 char 数组的前面,将较大的 block 放在另一端。所以,我基本上是使用两个链表来链接前面的 block 和后面的 block 。但是,我在初始化列表时遇到了奇怪的问题(在第一次调用 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 查看我在哪里遇到了段错误。它发生在 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
};

最佳答案

#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);

Actually, I am storing the pointer to the memblock in the memory array. The values of memblock are stored in stack.

不,他们不是。 smallrootbigroot 清楚地指向数组本身。

关于c++ - 奇怪的 C 堆栈内存覆盖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33138266/

相关文章:

c++ - 在 C++ 模板中处理字符串

c++ - 如何从 Rust 创建 C++ 对象?

c - 如何编辑代码分钟

memory - 匿名 mmap 零填充?

计算进程的内存使用

C++17 表达式求值顺序和 std::move

c++ - 避免模​​板参数中迭代器类型的累积

c - 通过Cygwin运行exe文件.错误输出:Segmentation fault(core dumped)

c - 如何在函数文件和项目文件中正确包含自己的库

c - 释放包含 void * 的结构