简体   繁体   English

通过将指针设置为NULL来初始化C中的堆栈

[英]Initialize a stack in C by setting pointer to NULL

I'm trying to implement stack in C according to the following header (stack.h): 我正在尝试根据以下标头(stack.h)在C中实现堆栈:

#ifndef STACK_H
#define STACK_H

/* An element from which stack is consisting */
typedef struct stack_node_ss {
  struct stack_node_ss *next;    /* pointer to next element in stack */
  void *value;                  /* value of this element */
} stack_node_s;

/* typedef so that stack user doesn't have to worry about the actual type of
 * parameter stack when using this stack implementation.
 */
typedef stack_node_s* stack_s;

/* Initializes a stack pointed by parameter stack. User calls this after he
 * has created a stack_t variable but before he uses the stack.
 */
void stack_init(stack_s *stack);

/* Pushes item to a stack pointed by parameter stack. Returns 0 if succesful,
 * -1 otherwise.
*/
int stack_push(void *p, stack_s *stack);

/* Pops item from a stack pointed by parameter stack. Returns pointer to
 * element removed from stack if succesful, null if there is an error or
 * the stack is empty.
 */
void *stack_pop(stack_s *stack);

#endif

However, being new with C, I'm stuck at the stack_init function, I have written in stack.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;
}

The main program begins with: 主程序开始于:

  int *tmp;
  stack_s stack;
  stack_init(&stack);

And this crashes my program with: 这使我的程序崩溃:

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;

Can you hint me to the right track? 你能提示我正确的方向吗? Many thanks. 非常感谢。

You have to allocate memory for **stack itself: 您必须为**stack本身分配内存:

*stack = malloc(sizeof(**stack));

But please don't typedef pointer types. 但是请不要使用typedef指针类型。 That's really confusing and hard to read. 这确实令人困惑并且难以阅读。 Better to pass the pointer by value and leave it to the caller to store the pointer, like this: 最好按值传递指针,然后将其留给调用方以存储指针,如下所示:

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.

Then you can just say: 然后,您可以说:

stack_node * s = create_stack();

// use s

destroy_stack(s);
s = NULL;  // some people like this

You are dereferencing an uninitialised pointer, causing undefined behaviour. 您正在取消引用未初始化的指针,从而导致未定义的行为。

Because this function is creating a new stack, you need to allocate some dynamic memory for the stack and then set the pointer to point to that newly allocated memory: 因为此函数正在创建一个新的堆栈,所以您需要为该堆栈分配一些动态内存,然后将指针设置为指向该新分配的内存:

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);

Then you should have a function called stack_destroy that will free the dynamic memory and set the pointer to NULL : 然后,您应该具有一个称为stack_destroy的函数,该函数将free动态内存并将指针设置为NULL

void stack_destroy(stack_s *stack) {
    free(*stack);
    *stack = NULL;
}

You should initialize the stack to NULL - not to push a NULL value to it: 您应该将堆栈初始化为NULL-不要向其推送NULL值:

void stack_init(stack_s *stack) {
    *stack=NULL;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM