我试图在C语言中创建一个链表,其中每个节点在程序启动时都有用户输入的特定大小。我已经想到了一个结构:
struct ListNode{
char * str;
struct ListNode * next_node;
};
,但是每个节点的大小是固定的。有什么想法吗?
非常感谢。
答案 0 :(得分:1)
似乎您需要节点每次更改的数据大小。您可以通过使用一个固定大小的节点来实现此目的,该节点拥有一个指向动态分配的数据的指针。
请注意,在下面的示例中,结构大小保持为sizeof(void *)+ sizeof(node *) 但是分配给每个节点的数据大小会根据用户输入而改变。
typedef struct Dnode
{
void* data;
struct Dnode* next;
}Dnode;
Dnode* CreateDnode(size_t data_size_bytes)
{
Dnode* newNode = NULL;
newNode = malloc(sizeof(Dnode));/*allways the same*/
if(NULL == newNode)
{
return NULL;
}
newNode->data = malloc(data_size_bytes);/*changes by input*/
if(NULL == newNode->data)
{
return NULL;
}
newNode->next = NULL;
return newNode;
}
答案 1 :(得分:0)
听起来像您正在寻找“柔性数组成员”功能,即将不完整的数组放置在结构的末尾:
struct ListNode {
struct ListNode *next;
char data[];
};
分配方式如下:
struct ListNode *node = malloc(sizeof *node + data_size_bytes);
然后,我们可以将node->data[i]
中的值从i
到0
存储在data_size_bytes - 1
中。整个结构和数据都在一个线性块中。
请注意,具有弹性成员的结构不能用作数组元素类型。
在ISO C标准于1999年添加灵活数组成员之前,这是使用大小为1的数组作为流行的“结构黑客”来完成的。如果您不得不在C90中工作,它将像这样:
struct ListNode {
struct ListNode *next;
char data[1];
};
现在sizeof ListNode
包含一个元素数组,和很可能是用于对齐的填充。例如,在具有四个字节指针的系统上,大小很可能为八。如果我们使用相同的malloc
行,则会分配过多的内存。用于C90结构破解的正确malloc
表达式:
#include <stddef.h>
struct ListNode *node = malloc(offsetof(struct ListNode, data) + data_size_bytes);
与灵活的数组成员功能不同,struct hack没有形式上明确定义的行为。只是“如果可行就行”。