通过将指针设置为NULL来初始化C中的堆栈
我正试图根据以下标题(stack.h)在C中实现堆栈: 但是,作为C的新手,我一直停留在stack_init函数上,我在stack.C中编写了:通过将指针设置为NULL来初始化C中的堆栈,c,null,initialization,linked-list,C,Null,Initialization,Linked List,我正试图根据以下标题(stack.h)在C中实现堆栈: 但是,作为C的新手,我一直停留在stack_init函数上,我在stack.C中编写了: #include <stdlib.h> #include <stdio.h> #include "stack.h" void stack_init(stack_s *stack) { (*stack)->value = NULL; (*stack)->next = NULL; } 这会使我的程序崩
#include <stdlib.h>
#include <stdio.h>
#include "stack.h"
void stack_init(stack_s *stack) {
(*stack)->value = NULL;
(*stack)->next = NULL;
}
这会使我的程序崩溃:
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x0000000000000008
0x0000000100000abf in stack_init (stack=0x7fff5fbffb30) at stack.c:6
6 (*stack)->value = NULL;
你能告诉我正确的路线吗?非常感谢。您必须为
**堆栈本身分配内存:
*stack = malloc(sizeof(**stack));
但请不要键入def指针类型。这真的很让人困惑,也很难理解。最好按值传递指针,并将其留给调用方存储指针,如下所示:
typedef struct stack_node_t
{
struct stack_node_t * next;
/* ... */
} stack_node;
stack_node * create_stack()
{
stack_node * res = calloc(1, sizeof(stack_node));
return res;
}
void destroy_stack(stack_node * s)
{
if (!next) return;
stack_node * next = s->next;
free(s);
destroy_stack(next);
}
// etc.
那么你可以说:
stack_node * s = create_stack();
// use s
destroy_stack(s);
s = NULL; // some people like this
您必须为**堆栈本身分配内存:
*stack = malloc(sizeof(**stack));
但请不要键入def指针类型。这真的很让人困惑,也很难理解。最好按值传递指针,并将其留给调用方存储指针,如下所示:
typedef struct stack_node_t
{
struct stack_node_t * next;
/* ... */
} stack_node;
stack_node * create_stack()
{
stack_node * res = calloc(1, sizeof(stack_node));
return res;
}
void destroy_stack(stack_node * s)
{
if (!next) return;
stack_node * next = s->next;
free(s);
destroy_stack(next);
}
// etc.
那么你可以说:
stack_node * s = create_stack();
// use s
destroy_stack(s);
s = NULL; // some people like this
您正在取消对未初始化指针的引用,从而导致未定义的行为
由于此函数正在创建新堆栈,因此需要为堆栈分配一些动态内存,然后将指针设置为指向新分配的内存:
void stack_init(stack_s *stack) {
*stack = malloc(sizeof(**stack)); // create memory for the stack
(*stack)->value = NULL;
(*stack)->next = NULL;
}
stack_s stack;
stack_init(&stack);
然后您应该有一个名为stack\u destroy
的函数,它将释放动态内存并将指针设置为NULL
:
void stack_destroy(stack_s *stack) {
free(*stack);
*stack = NULL;
}
您正在取消对未初始化指针的引用,从而导致未定义的行为
由于此函数正在创建新堆栈,因此需要为堆栈分配一些动态内存,然后将指针设置为指向新分配的内存:
void stack_init(stack_s *stack) {
*stack = malloc(sizeof(**stack)); // create memory for the stack
(*stack)->value = NULL;
(*stack)->next = NULL;
}
stack_s stack;
stack_init(&stack);
然后您应该有一个名为stack\u destroy
的函数,它将释放动态内存并将指针设置为NULL
:
void stack_destroy(stack_s *stack) {
free(*stack);
*stack = NULL;
}
您应该将堆栈初始化为NULL-不要将NULL值推送到堆栈:
void stack_init(stack_s *stack) {
*stack=NULL;
}
您应该将堆栈初始化为NULL-不要将NULL值推送到堆栈:
void stack_init(stack_s *stack) {
*stack=NULL;
}
这就是为什么你不把指针类型隐藏在typedefs后面,除非有很好的理由。@Ed S:没错。甚至typedef结构{…}mystruct\t代码>有问题,伊姆霍。为什么这种做法仍然在学校里教授?在我看来,所有的老师都遭受着极端形式的帕斯卡主义的折磨。@wildplasser:嗯。。。当我写C时,我将typedef
a struct以避免写struct foo f代码>无处不在。我不认为这是有问题的,但是对于指针类型。。。有龙。这就是为什么你不在typedef后面隐藏指针类型,除非有很好的理由。@Ed S:没错。甚至typedef结构{…}mystruct\t代码>有问题,伊姆霍。为什么这种做法仍然在学校里教授?在我看来,所有的老师都遭受着极端形式的帕斯卡主义的折磨。@wildplasser:嗯。。。当我写C时,我将typedef
a struct以避免写struct foo f代码>无处不在。我不认为这是有问题的,但是对于指针类型。。。有龙。这是我见过的最无用的init
函数。。。但它并没有解决这个问题-1@EdS.我知道这没用,但OP需要一个函数。。。他试图将NULL推送到无效地址,但没有理由这样做。他所需要的只是将NULL赋值给他得到的堆栈。(推送东西需要分配)不,他有一个init
函数,人们希望你以后能够使用堆栈。您的实现只是保证您不能这样做。OP的问题是他没有意识到函数的输入应该是指向堆栈指针的有效指针。他声明了一个指向堆栈的指针(通过typdef隐藏),但从未初始化它。如果有什么事情你应该做相反的事情<代码>malloc
当时就在那里。@EdS.为什么它不可用?要推送值,请为其分配空间,将值放入其中,使其下一个点指向当前的第一个成员(即**堆栈
,而不是(*堆栈)->下一个
),并使*堆栈
指向它。你能解释一下行(*stack)->value=NULL在赛斯的回答中,code>已经是一个指针,所以stack.*
是指向指针的指针。这就是为什么有两个解引用。这允许您初始化参数。函数将指针设置为NULL。。。现在这意味着它不能被使用。我看不出这有什么用处,也没有进行初始化。如果我调用init
我希望得到一个有效的对象作为回报。这是我见过的最无用的init
函数。。。但它并没有解决这个问题-1@EdS.我知道这没用,但OP需要一个函数。。。他试图将NULL推送到无效地址,但没有理由这样做。他所需要的只是将NULL赋值给他得到的堆栈。(推送东西需要分配)不,他有一个init
函数,人们希望你以后能够使用堆栈。您的实现只是保证您不能这样做。OP的问题是他没有意识到函数的输入应该是指向堆栈指针的有效指针。他声明了一个指向堆栈的指针(通过typdef隐藏),但从未初始化它。如果有什么事情你应该做相反的事情<代码>malloc
当时就在那里。@EdS.为什么它不可用?要推送值,请为其分配空间,将值放入其中,使其下一个点指向当前的第一个成员(即**堆栈
,而不是(*堆栈)->下一个
),并使*堆栈
指向它。你能解释一下行(*stack)->value=NULL在赛斯的回答中,code>已经是一个指针,所以stack.*
是指向指针的指针。这就是为什么有两个解引用。这允许您初始化参数。函数将指针设置为NULL。。。现在这意味着它不能被使用。我不明白这是怎么回事