我正在尝试在预先分配的内存块中创建链接列表。简单地说,
我有一个像这样声明的初始内存池。
void *block = malloc(1000);
我从这个池中创建了一个链表的头部:
struct node *root = block;
假设初始块的内存地址是100000.如果我添加一个大小为100的链表节点,这只是从100000开始(因为它是第一个节点,共享第一个节点的内存地址)块)。如果我添加大小为200的第二个节点,则应该从100100开始(在最后一个块的末尾)。下一个将从100300开始,依此类推。
我将节点添加到列表的方法可以压缩如下:
void add_node(int size) {
new_node = malloc(sizeof(struct node));
struct node *current = root;
while (current != NULL) { //loop to get to the end of the linked list
...stuff (irrelevant to this question)...
current = current->next;
}
new_node->value = size;
current->next = new_node;
}
节点定义非常通用:
struct node {
int value;
int free;
struct node *next;
};
主要方法如下:
int main(void) {
create_block(1000);
add_node(100);
add_node(200);
print_all();
}
print_all只是遍历并打印出内存地址:
void print_all() {
printf("%ld (block start)\n", block);
struct node* current = root;
while (current != NULL) {
printf("%ld (%d)", current->value);
current = current->next;
}
}
但是,添加值为100和200的节点时,内存地址如下:
25770205072(块开始) 25770205072(100个节点的位置 - 这没关系) 25769968848(200节点的位置 - 不行。这应该是25770205072 + 100) 25770204784(剩余700个内存节点的位置 - 不行。这应该是25770205072 + 100 + 200)
我做错了什么的线索?我尝试了几种不同的方法而没有任何运气。
感谢您的时间!我非常感谢你的任何帮助。
答案 0 :(得分:0)
警告:由于您没有显示池代码,这可能不是一个完整的解决方案,但add_node
有一些错误。
您必须设置new_node->next = NULL
在循环结束时,current
可能为null,除非“无关紧要的东西......”保证非空。在这种情况下,它不无关紧要。
您需要一个额外的变量(例如prev
)
另请注意,由于add_node
正在调用malloc
,因此它会绕过您的内存池,因此您不能对地址抱有太多期望。
这是我认为你需要的[请原谅无偿的风格清理]:
void
add_node(int size)
{
struct node *new_node = malloc(sizeof(struct node));
struct node *current;
struct node *prev;
// loop to get to the end of the linked list
prev = root;
for (current = root; current != NULL; current = current->next) {
// ... stuff(irrelevant to this question) ...
prev = current;
}
new_node->value = size;
new_node->next = NULL;
// NOTE: this assumes root is _always_ non-null
#if 0
prev->next = new_node;
#else
if (prev != NULL)
prev->next = new_node;
else
root = new_node;
#endif
}
答案 1 :(得分:0)
实际上,这很简单。我确实使用了@Ajay Brahmakshatriya提到的 - “你可以保留一个从根开始并按大小递增的计数器” - 并创建一个从根开始的新长度,并且每次都按大小递增。我没有将新节点设置为新的已分配内存blob,而是将其设置为旧地址+大小(并适当增加地址)。现在工作正常!谢谢!
答案 2 :(得分:0)
我只是尝试记住“链表”概念...... 它不同于阵列中每个元素位于存储器之前与元素完全相邻/相邻的数组。
我认为每个节点都“动态分配”。程序尝试找到仍然空闲的内存,并且某个当前节点可以位于远离前一节点的位置。但是分配节点的大小块取决于我们如何编写malloc代码,大小来分配它。
所以我认为你的代码没有错......