我正在编写一个需要创建可变数量的链表的程序。在程序开始时全局声明以下内容:
struct Node
{
int Line;
struct Node *Next;
} ;
struct Node* Heads[5];
struct Node* Currs[5];
int NumOfNames;
main()
中的第一个函数将计算并存储NumOfNames
的值。然后我需要将Heads[5]
和Currs[5]
的大小更改为Heads[NumOfNames]
和Currs[NumOfNames]
,以便创建NumOfNames
数量的链接列表。可以做这些事情吗?
我对编程很陌生,我对malloc
和realloc
的了解非常差,但我认为我需要使用这些函数来实现我的目标。
提前感谢您的任何建议。
答案 0 :(得分:3)
你需要这个:
struct Node
{
int Line;
struct Node *Next;
} ;
struct Node** Heads;
struct Node** Currs;
int NumOfNames ;
main()
{
int NumOfNames = ... ; // calculate the number of names
...
Heads = malloc(NumOfNames * sizeof (struct Node*));
// now Heads point to an array of pointers to struct Node of length NumOfNames
...
Heads[1] = malloc(sizeof (struct Node));
...
}
答案 1 :(得分:2)
停止使用静态数组,并在运行时分配:
struct Node* Heads;
struct Node* Currs;
Heads = malloc(NumOfNames * sizeof *Heads);
Currs = malloc(NumOfNames * sizeof *Currs);
然后,您可以通过Heads[0]
(包括)访问Heads[NumOfNames - 1]
,假设分配当然成功。
答案 2 :(得分:1)
你所拥有的是static allocation并且内存是在堆栈上分配的(实际上并非真正在堆栈上,因为这些是全局变量 - 请参阅注释)。这意味着需要在编译时知道数组的大小。另一方面,您希望能够在运行时分配内存,因为您之前不知道大小(NumOfNames
)。这称为dynamic allocation,您需要malloc
(或calloc
,...)。这样的内存在堆上分配。有关这方面的更多信息,请阅读例如这些:
使用malloc
做你想做的事情,你可以这样做:
struct Node
{
int Line;
struct Node *Next;
} ;
struct Node** Heads;
struct Node** Currs;
int NumOfNames;
int main() {
// ...
NumOfNames = 42;
Heads = malloc(NumOfNames * sizeof(struct Node*));
Currs = malloc(NumOfNames * sizeof(struct Node*));
// if you want to allocate the Nodes too...
int i;
for (i = 0; i < NumOfNames; i++) {
Heads[i] = malloc(sizeof(struct Node));
Currs[i] = malloc(sizeof(struct Node));
}
// ...
}
当您动态分配内存时(使用malloc
,calloc
,realloc
,...),请确保在{39}时{和}}不再需要了。
答案 3 :(得分:1)
如果您被允许使用C99(gcc标记为-std=c99
),则可以使用variable length arrays。 Here也是。
// From the wikipedia page
float read_and_process(int n)
{
float vals[n];
for (int i = 0; i < n; i++)
vals[i] = read_val();
return process(vals, n);
}
您的Heads
和Currs
可以使用变量作为大小。另一方面,你不能使它们全局化,你必须将指针和大小传递给子函数。
另请注意,如果您不熟悉编程和C,则使用malloc
和free
是您真正想要学习的内容。
另请注意,VLA是not very popular,例如,如果没有足够的内存为它们分配空间,它们不会返回错误,可能导致难以调试和危险的问题。
我觉得我必须写下这个替代方案,但我也认为你应该选择malloc
和free
,并了解这是如何完成的。检查malloc
是否返回NULL
并正常退出:)