首页 > 解决方案 > C中的结构指针

问题描述

结构问题。

我写了一个实现堆栈的代码。如果我将 sqStack* sq 传递给这个函数 init_stack(),代码最终会出错。如以下代码的注释所示。
但后来我发现如果我将 sqStack &sq 传递给 init_stack() 函数,代码就可以工作。
谁能给我解释一下?谢谢!

#include <stdio.h>
#include <stdlib.h>

#define init_size 10
#define increment 1

typedef struct sqStack
{
    int* top;
    int* base;
    int stack_size;
}sqStack;

int init_stack(sqStack* sq)
{
    if(sq->base==NULL)
    {
       sq->base = (int*)malloc(init_size*sizeof(int));
    }
    if(sq->base==NULL) exit(-1);
    sq->stack_size=init_size;
    sq->top=NULL;
    sq->top=sq->base;
    return 1;
}
int push(sqStack* sq, int e)
{
    if(sq==NULL) exit(-1);
    if(sq->top-sq->base==sq->stack_size)
    {
        int* q = (int*)realloc(sq->base,  
        (init_size+increment)*sizeof(int));
        if(q==NULL) exit(-1);
        sq->base=q;
        sq->stack_size += increment;
        sq->top=sq->base+sq->stack_size;

    }
    *sq->top++=e;//Thread 1: EXC_BAD_ACCESS  If I pass sqStack* sq to this function, error occurs. But if I pass sqStack &sq, the code works.


    return 1;
}

int pop(sqStack* sq,int*e)
{
    if(sq==NULL) exit(-1);  
    if(sq->base==sq->top)  exit(-1);   
    sq->top-=1;   
    *e=*sq->top;   
    return 1;    
}

int empty(sqStack* sq)
{
    if(sq->base==sq->top) return 1;
    else return 0;
}


int main()
{
    sqStack* sq;
    init_stack(sq);
    push(sq,1);
    int e=
    pop(sq,e);
    printf("%d\n",*e);
/* sqStack sq;
    init_stack(&sq);
    push(&sq,1);
    int e;
    pop(&sq,&e);
    printf("%d\n",e);*/
    return 0;
}

在任何一种情况下,输出都是 1。

标签: cpointersstruct

解决方案


在这里,您取消引用未初始化(悬空)的指针:

sqStack* sq;
init_stack(sq);

(在 init_stack() 中):

if(sq->base==NULL)
   ...

这会立即导致未定义的行为。

最好这样做:

sqStack sq;
init_stack(&sq);

现在您在进程堆栈上为 sqStack 正确分配空间,并将指向该空间的指针传递给init_stack(). 每次你想传递一个指向那个结构的指针(例如 inpoppush)你现在必须使用&sq

或者,您可以sqStack像这样动态分配内存:

sqStack *sq = malloc(sizeof(sqStack));
init_stack(sq);

它还保留内存(这次是在堆上)。

第三种变体是将结构的分配留给init_stack()函数。在这种情况下,您必须将双指针传递给init_stack,以便可以将地址写入其中(错误检查要自己添加):

int init_stack(sqStack** _sq) {
    sqStack* sq;
    sq = *_sq = malloc(sizeof(sqStack));
    sq->base = malloc(init_size*sizeof(int));
    ...

在你的主要:

sqStack *sq;
init_stack(&sq);
...

推荐阅读