Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-apps-script/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过将指针设置为NULL来初始化C中的堆栈_C_Null_Initialization_Linked List - Fatal编程技术网

通过将指针设置为NULL来初始化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; } 这会使我的程序崩

我正试图根据以下标题(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;
}
这会使我的程序崩溃:

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已经是一个指针,所以
stack.*
是指向指针的指针。这就是为什么有两个解引用。这允许您初始化参数。函数将指针设置为NULL。。。现在这意味着它不能被使用。我看不出这有什么用处,也没有进行初始化。如果我调用
init
我希望得到一个有效的对象作为回报。这是我见过的最无用的
init
函数。。。但它并没有解决这个问题-1@EdS.我知道这没用,但OP需要一个函数。。。他试图将NULL推送到无效地址,但没有理由这样做。他所需要的只是将NULL赋值给他得到的
堆栈。(推送东西需要分配)不,他有一个
init
函数,人们希望你以后能够使用堆栈。您的实现只是保证您不能这样做。OP的问题是他没有意识到函数的输入应该是指向堆栈指针的有效指针。他声明了一个指向堆栈的指针(通过typdef隐藏),但从未初始化它。如果有什么事情你应该做相反的事情<代码>malloc
当时就在那里。@EdS.为什么它不可用?要推送值,请为其分配空间,将值放入其中,使其下一个点指向当前的第一个成员(即
**堆栈
,而不是
(*堆栈)->下一个
),并使
*堆栈
指向它。你能解释一下行
(*stack)->value=NULL已经是一个指针,所以
stack.*
是指向指针的指针。这就是为什么有两个解引用。这允许您初始化参数。函数将指针设置为NULL。。。现在这意味着它不能被使用。我不明白这是怎么回事