动态列表中的Malloc函数
我刚开始学习动态列表,我不明白为什么在main()程序中声明第一个节点时也需要使用malloc函数,下面的代码应该只打印第一个节点中包含的数据,但是如果我不使用malloc函数初始化节点,它就无法工作:动态列表中的Malloc函数,c,list,dynamic,C,List,Dynamic,我刚开始学习动态列表,我不明白为什么在main()程序中声明第一个节点时也需要使用malloc函数,下面的代码应该只打印第一个节点中包含的数据,但是如果我不使用malloc函数初始化节点,它就无法工作: struct node{ int data; struct node* next; }; void insert(int val, struct node*); int main() { struct node* head ; head->data =
struct node{
int data;
struct node* next;
};
void insert(int val, struct node*);
int main() {
struct node* head ;
head->data = 2;
printf("%d \n", head->data);
}
从技术上讲,您不需要这样做,但是使用相同的内存模式维护所有节点对您来说只是一个优势,没有实际的缺点 假设所有节点都存储在动态内存中 您的“insert”过程最好命名为“add”或(对于完整的功能上下文)“cons”,它应该返回新节点:
struct node* cons(int val, struct node* next)
{
struct node* this = (struct node*)malloc( sizeof struct node );
if (!this) return next; // or some other error condition!
this->data = val;
this->next = next;
return this;
}
创建列表现在非常简单:
int main()
{
struct node* xs = cons( 2, cons( 3, cons( 5, cons( 7, NULL ) ) ) );
// You now have a list of the first four prime numbers.
而且很容易处理它们
// Let’s print them!
{
struct node* p = xs;
while (p)
{
printf( "%d ", p->data );
p = p->next;
}
printf( "\n" );
}
// Let’s get the length!
int length = 0;
{
struct node* p = xs;
while (p)
{
length += 1;
p = p->next;
}
}
printf( "xs is %d elements long.\n", length );
顺便说一下,在命名事物时,你应该尽量保持一致。您已将节点数据命名为“data”,但构造函数的参数将其称为“val”。你应该选一个并坚持下去
此外,常见的情况是:
typedef struct node node;
现在,除了在struct node
的定义中,您可以在每个地方使用node
这个词
哦,我差点忘了:别忘了用合适的析构函数来清理
node* destroy( node* root )
{
if (!root) return NULL;
destroy( root->next );
free( root );
return NULL;
}
以及main()
的附录:
从技术上讲,您不需要这样做,但是使用相同的内存模式维护所有节点对您来说只是一个优势,没有实际的缺点 假设所有节点都存储在动态内存中 您的“insert”过程最好命名为“add”或(对于完整的功能上下文)“cons”,它应该返回新节点:
struct node* cons(int val, struct node* next)
{
struct node* this = (struct node*)malloc( sizeof struct node );
if (!this) return next; // or some other error condition!
this->data = val;
this->next = next;
return this;
}
创建列表现在非常简单:
int main()
{
struct node* xs = cons( 2, cons( 3, cons( 5, cons( 7, NULL ) ) ) );
// You now have a list of the first four prime numbers.
而且很容易处理它们
// Let’s print them!
{
struct node* p = xs;
while (p)
{
printf( "%d ", p->data );
p = p->next;
}
printf( "\n" );
}
// Let’s get the length!
int length = 0;
{
struct node* p = xs;
while (p)
{
length += 1;
p = p->next;
}
}
printf( "xs is %d elements long.\n", length );
顺便说一下,在命名事物时,你应该尽量保持一致。您已将节点数据命名为“data”,但构造函数的参数将其称为“val”。你应该选一个并坚持下去
此外,常见的情况是:
typedef struct node node;
现在,除了在struct node
的定义中,您可以在每个地方使用node
这个词
哦,我差点忘了:别忘了用合适的析构函数来清理
node* destroy( node* root )
{
if (!root) return NULL;
destroy( root->next );
free( root );
return NULL;
}
以及main()
的附录:
声明变量时,定义变量的类型,然后 名称,并可以选择声明其初始值 每种类型都需要特定数量的内存。例如,
int
将是
32位操作系统为32位,64位操作系统为8位
函数中声明的变量通常存储在相关的堆栈中
具有该功能。当函数返回时,该函数的堆栈为
不再可用,且变量不再存在
当您需要变量的值/对象即使在函数之后也存在时
返回,然后需要在程序的不同部分分配内存,
通常是堆。这正是malloc
、realloc
和calloc
所做的
做
这完全是错误的。您已经声明了一个名为head
的指针,其类型为struct node
,
但你没有给它分配任何东西。因此,它指向一个未指明的目标
内存中的位置head->data=2
尝试在未指定的位置存储值
位置和程序很可能会因segfault而崩溃
大体上,您可以这样做:
int main(void)
{
struct node head;
head.data = 2;
printf("%d \n", head.data);
return 0;
}
head
将保存在堆栈中,只要main
没有保存,它就会一直存在
回来但这只是一个很小的例子。在一个复杂的程序中
拥有更多的变量、对象等。简单地声明所有
在main
中需要的变量。因此,最好在创建对象时创建它们
这是需要的
例如,您可以有一个创建对象和另一个对象的函数
调用create\u node
并使用该对象
struct node *create_node(int data)
{
struct node *head = malloc(sizeof *head);
if(head == NULL)
return NULL; // no more memory left
head->data = data;
head->next = NULL;
return head;
}
struct node *foo(void)
{
struct node *head = create_node(112);
// do somethig with head
return head;
}
这里create\u节点
使用malloc为一个struct节点分配内存
对象,使用一些值初始化该对象,并返回指向该内存位置的指针。
foo
调用create\u节点
并对其执行操作,然后返回
对象如果另一个函数调用foo
,此函数将获取对象
malloc
还有其他原因。考虑这个代码:
void foo(void)
{
int numbers[4] = { 1, 3, 5, 7 };
...
}
在这种情况下,您知道需要4个整数。但有时你需要一个
例如,仅在运行时知道元素数的数组
因为它依赖于一些用户输入。为此,您还可以使用malloc
void foo(int size)
{
int *numbers = malloc(size * sizeof *numbers);
// now you have "size" elements
...
free(numbers); // freeing memory
}
使用malloc
、realloc
、calloc
时,需要释放内存。如果
您的程序不再需要内存,您必须使用free
(如
最后一个例子。请注意,为了简单起见,我省略了
带有
struct head的示例
声明变量时,定义变量的类型,然后
名称,并可以选择声明其初始值
每种类型都需要特定的内存量。例如int
32位操作系统为32位,64位操作系统为8位
函数中声明的变量通常存储在相关的堆栈中
当函数返回时,该函数的堆栈
不再可用,且变量不再存在
当您需要变量的值/对象即使在函数之后也存在时
返回,然后需要在程序的不同部分分配内存,
通常是堆。这正是malloc
、realloc
和calloc
所做的
做
是错误的。您声明了一个名为head
的指针,其类型为struct node
,
但是你没有给它赋值,所以它指向一个未指定的
内存中的位置。head->data=2
尝试存储
int main() {
int myInt; // creates space for an actual int in automatic storage (most likely the stack)
int* head = &myInt; // now head points to a valid memory location, namely myInt
*head = 2; // now myInt == 2
printf("%d\n", *head); // prints 2
return 0;
}
int main() {
int* head = malloc(sizeof int); // silly to malloc a single int, but this is for illustration purposes
if (head != NULL)
{
// space for an int was returned to us from the heap
*head = 2; // now the unnamed int that head points to is 2
printf("%d\n", *head); // prints out 2
// don't forget to clean up
free(head);
}
else
{
// handle error, print error message, etc
}
return 0;
}
int main() {
struct node* head = calloc(1, sizeof(struct node));
if (head) {
head->data = 2;
printf("%d \n", head->data);
free(head);
}
}
int main() {
struct node head;
head.data = 2;
printf("%d \n", head.data);
}