Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.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
C语言中的结构指针_C_Pointers_Struct - Fatal编程技术网

C语言中的结构指针

C语言中的结构指针,c,pointers,struct,C,Pointers,Struct,结构问题 我编写了一个实现堆栈的代码。如果我将sqStack*sq传递给这个函数init_stack,代码将以一个错误结束。如下面代码的注释所示。 但后来我发现,如果我将sqStack&sq传递给init_stack函数,代码就会工作。 谁能给我解释一下吗?谢谢 #include <stdio.h> #include <stdlib.h> #define init_size 10 #define increment 1 typedef struct sqStack {

结构问题

我编写了一个实现堆栈的代码。如果我将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。

这里您取消了对未初始化悬挂指针的引用:

sqStack* sq;
init_stack(sq);
在init_堆栈中:

if(sq->base==NULL)
   ...
这会立即导致未定义的行为

最好这样做:

sqStack sq;
init_stack(&sq);
现在,在进程堆栈上为sqStack正确分配空间,并将指向该空间的指针传递给init_堆栈。每次您想要传递指向该结构的指针时(例如,在pop和push中),您必须立即使用&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);
...

在这里,您将取消引用未初始化的悬挂指针:

sqStack* sq;
init_stack(sq);
在init_堆栈中:

if(sq->base==NULL)
   ...
这会立即导致未定义的行为

最好这样做:

sqStack sq;
init_stack(&sq);
现在,在进程堆栈上为sqStack正确分配空间,并将指向该空间的指针传递给init_堆栈。每次您想要传递指向该结构的指针时(例如,在pop和push中),您必须立即使用&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);
...
问题解决方案 问题在于你保留了记忆 将sq用作指针。为什么会有问题

嗯,我们只有空间来存放sqStack的地址。 如果我们将sq传递给init_堆栈,我们将取消引用 sq.这不会导致任何结果,因为我们将其初始化为 指针,因此,如果我们试图给它的字段赋值, 我们没有空间放它

如何解决这个问题?只需将sq初始化为 sqStack而不是指向它的指针:

sqStack sq;
init_stack(&sq);  /* pass by reference here */
/* code continued */
建议 另外,我认为更好的结构应该是

typedef struct sqStack {
  int *elements;
  int top;
}
通过这种方式,您可以使用顶部作为跟踪的手段 只需将元素存储在 特别分配的数组。这样看起来

void push(sqStack *sq, int element) {
  sq->top++;
  if (sq->top - 1 == 0) {
    /* we need to allocate space */
    sq->elements = malloc(sizeof(int));
  } else {
    /* we need to reallocate space */
    sq->elements = realloc(sq->elements, sq->top * sizeof(int));
  }
  sq->elements[sq->top - 1] = element;
}
…并以类似方式修改其他功能。但是 这只是一个建议。

问题解决方案 问题在于你保留了记忆 将sq用作指针。为什么会有问题

嗯,我们只有空间来存放sqStack的地址。 如果我们将sq传递给init_堆栈,我们将取消引用 sq.这不会导致任何结果,因为我们将其初始化为 指针,因此,如果我们试图给它的字段赋值, 我们没有空间放它

如何解决这个问题?只需将sq初始化为 sqStack而不是指向它的指针:

sqStack sq;
init_stack(&sq);  /* pass by reference here */
/* code continued */
建议 另外,我认为更好的结构应该是

typedef struct sqStack {
  int *elements;
  int top;
}
通过这种方式,您可以使用顶部作为跟踪的手段 只需将元素存储在 特别分配的数组。这样看起来

void push(sqStack *sq, int element) {
  sq->top++;
  if (sq->top - 1 == 0) {
    /* we need to allocate space */
    sq->elements = malloc(sizeof(int));
  } else {
    /* we need to reallocate space */
    sq->elements = realloc(sq->elements, sq->top * sizeof(int));
  }
  sq->elements[sq->top - 1] = element;
}
…并以类似方式修改其他功能。但是
这只是一个建议。

在主函数中有指针sq,但它指向哪里?我建议您将其更改为非指针,并使用运算符的地址&当需要指向它的指针时。&基本上是指指向的指针。这是一个经典问题。返回分配的节点或使用指向指针的指针。在C语言中,应该将指向X的指针传递给希望修改X的函数。在这种情况下,由于您希望修改指针,因此应该将指针传递给指针。在main函数中,您有指针sq,但它指向哪里?我建议您将其更改为非指针,并使用运算符的地址&当需要指向它的指针时。&基本上是指指向的指针。这是一个经典问题。返回分配的节点或使用指向指针的指针。在C语言中,应该将指向X的指针传递给希望修改X的函数。在这种情况下,因为您希望修改指针,所以应该将指针传递给指针。谢谢!并且是sq->top=NULL;在init_堆栈中,代码中需要用到???@Liu No,因为您在下一行sq->top=sq->base中覆盖了它;你可以省略这个,谢谢!我现在知道我的代码有问题,但是为什么我用同样的方法创建一个序列,结果很好,为什么?如果我动态地为sqStack sqStack*sq=mallocsizeofsqStack分配内存;init_stacksq;sq没有初始化,在将其传递给push之后,代码被压碎了,我应该如何修复它??@Li

你必须显示完整的代码,即编辑你的问题并将其添加到那里谢谢!并且是sq->top=NULL;在init_堆栈中,代码中需要用到???@Liu No,因为您在下一行sq->top=sq->base中覆盖了它;你可以省略这个,谢谢!我现在知道我的代码有问题,但是为什么我用同样的方法创建一个序列,结果很好,为什么?如果我动态地为sqStack sqStack*sq=mallocsizeofsqStack分配内存;init_stacksq;sq未初始化,在将其传递到push后,代码被压碎,我应该如何修复它???@Liu您必须显示完整的代码,即编辑您的问题并将其添加到那里谢谢!并且是sq->top=NULL;在代码中需要的init_堆栈中???@Liu我添加了一个间接解决您问题的建议。一个建议??谢谢!我现在知道我的代码有问题,但是为什么我用类似的方法创建序列,结果很好,为什么?谢谢!并且是sq->top=NULL;在代码中需要的init_堆栈中???@Liu我添加了一个间接解决您问题的建议。一个建议??谢谢!我现在知道我的代码有问题,但为什么我用类似的方法创建序列,结果很好,为什么??