【发布时间】:2017-08-10 19:51:17
【问题描述】:
背景: 我正在完成一个项目,其目标是构建一个复制 malloc() 和 free() 的内存管理系统。该程序首先使用 mmap 从操作系统请求指定数量的内存,然后使用链表跟踪哪些内存部分正在使用或空闲。请参阅下文,大致了解我在做什么。
Output after allocating one chunk of memory
问题 为什么我在尝试创建新的列表节点来表示可用内存时遇到分段错误?仅当尝试请求两个以上的内存块时才会出现此分段错误 - 第一个按预期工作。
详情 当试图为刚刚创建的节点(下面代码中的new)的属性分配值以表示剩余的可用内存空间时,会发生分段错误。此分配在我第一次将内存拆分为已用 v. 空闲段时有效,但第二次尝试将空闲内存拆分为已用 v. 空闲段时,我的程序遇到了分段错误 - 我假设发生这种情况是因为新的 node_t 结构未定义(编译器不知道它们在内存中的位置)。 我不知道为什么会发生这种情况,以及为什么我第一次使用此代码时没有发生这种情况。
注意: 答案不应该是在初始化 *new 节点时使用 malloc,因为项目的重点是在不使用 malloc 的情况下执行此操作。 Malloc 不会从我正在管理的内存中分配 - 相反,它会从我的程序实际维护(但不使用)的堆中分配。
结构定义:
typedef enum {false, true} bool;
typedef struct _node_t {
int size;
struct _node_t *next;
struct _node_t *prev;
bool used;
} node_t;
问题代码。 ret 是我要返回给调用者的内存分配,而 new 是我刚刚分配的空闲内存块的剩余部分。
// Code above this steps through the list elements to find the first free
// element that is large enough. I've debugged enough to know that's not the
// source of the problem.
node_t *new = ret + sizeof(node_t) + size; // Pointer to new free slot
assert(new != NULL);
new->prev = ret;
new->next = ret->next;
new->size = ret->size - sizeof(node_t) - size;
new->used = false;
ret->used = true;
ret->next = new;
ret->size = size;
return (ret + sizeof(node_t));
调用代码:
int main(int argc, char* argv[]) {
int success = Mem_Init(5000, P_FIRSTFIT);
if (success == -1)
return -1;
int *slot1 = Mem_Alloc(sizeof(int));
// This is where segmentation fault occurs
int *slot2 = Mem_Alloc(sizeof(int));
Link 可以编译和运行的代码。
【问题讨论】:
-
除此之外,您的代码不是minimal reproducible example。请修改。
-
@DouglasAnsel 我可以自己编译和运行以复制问题的代码在哪里?
-
@DouglasAnsel ... 正如链接中所说:“完成 - 提供重现问题所需的所有部分”
-
@DouglasAnsel "寻求调试帮助的问题(“为什么这段代码不起作用?”)必须包括所需的行为、特定问题或错误以及重现它所需的最短代码 在问题本身。“如果要发布的代码太多,那可能不是最少的。
标签: c pointers memory-management