C++内存分配和链表实现

3
我正在编写软件来模拟“首次适应”内存分配方案。
基本上,我会分配一个大的X兆字节的内存块,并在根据该方案请求块时将其细分为块。
我使用一个称为“节点”的链表作为每个内存块的标题(这样我们可以找到下一个块而不必费力循环遍历每个地址值)。
head_ptr = (char*) malloc(total_size + sizeof(node));

if(head_ptr == NULL) return -1; // Malloc Error .. :-(

node* head_node = new node; // Build block header

head_node->next = NULL;
head_node->previous = NULL;

// Header points to next block (which doesn't exist yet)
memset(head_ptr,head_node, sizeof(node));

但是这最后一行返回:
 error: invalid conversion from 'node*' to 'int'

我理解为什么这是无效的,但是我如何将我的节点放入新分配的内存指针位置呢?


是的,我的问题涉及语法帮助,而不是理论。 - pws5068
4个回答

2
memset(void* memory, int value, size_t size)

因此,这不是将head_node复制到head_ptr中(你在考虑memcpy),而是用于初始化内存(清除为0,标记为已释放等)。
在这种情况下,您可以将head_ptr简单地强制转换为node*
node* head_node = (node*)head_ptr;

现在你不必删除head_node,也不必复制值到head_ptr


感谢您提供这个优雅的解决方案。您是正确的,我混淆了memset和memcpy的目的,我看到它也可以工作。 - pws5068

1

阅读文档。memset函数的第二个参数是一个整数(但被解释为unsigned char)。这指定了要设置内存区域的前n个字节的值,其中n是第三个参数。

您可以使用memcpy函数将一个内存区域复制到另一个内存区域。尝试:

memcpy(head_ptr, head_node, sizeof(node));

编辑:另一种选择是使用指针转换 head_ptr 来设置前一个和后一个值,正如 Simon 所建议的那样。


1
如果我正确理解您的问题,您想将节点对象构造到由head_ptr分配和指向的内存中。如果您需要调用节点构造函数,可以通过placement new运算符进行操作,例如:
node* head_node = new(head_ptr) node;

如果您确实需要确保析构函数被调用,那么您必须手动调用delete:

head_node->~node();

如果他正在使用“放置new”,那么他也应该使用“放置delete”——在没有“节点”的定义的情况下不能做出任何假设。很有可能“放置new”可以完全跳过,因为它可能只是一个愚蠢的“结构体”。 - vladr
放置new将是new (head_ptr) node,您正在使用head_ptr作为参数构造一个node - Simon Buchan
1
@Vlad:挑剔一点,但C++保证放置删除是无操作的。 new(ptr)T的反向操作是ptr->〜T() - Simon Buchan
@Simon,我提出这个问题的原因是我们不知道他的“node”是否是一个简单结构体,也就是说,他的析构函数是否真的有用(我们可能不知道他的“node”中是否有一个需要被销毁的“std::string”成员变量。) :) - vladr
@Vlad:这就是为什么知道 delete (ptr) T 不起作用非常重要。你必须手动调用析构函数。 - Simon Buchan

0

你不能这样分配指针。第二个参数是要重复的int

来自memset(3)

概述
     #include <string.h>
void * memset(void *b, int c, size_t len);
描述 memset()函数将值c(转换为无符号字符)的len个字节写入字节字符串b。
返回值 memset()函数返回其第一个参数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接