C - 带有struct的分段错误

时间:2015-03-31 18:29:58

标签: c struct segmentation-fault stack

如果这是一个容易解决的问题,我真的很抱歉,但我是初学者。 我有一个将一些函数写入stack-struct的赋值。给出了结构。我无法摆脱push()line" s->元素中的分段错误......" 在谷歌搜索和搜索后,我不知道出了什么问题。

这里的代码:

#define STACK_SIZE 5

#include <stdio.h> #include <stdlib.h> typedef struct stackADT { int elements[STACK_SIZE]; int count; } stack; void initialize(stack *s) { stack *newStack; newStack = malloc(sizeof(*newStack)); newStack->count = 0; s = newStack; } int push(stack *s, int value) { if(s->count == 5) return -1; else { s->elements[s->count++] = value; return s->elements[s->count-1]; } } int main() { stack* sA; stack* sB; initialize(sA); initialize(sB); printf("%d\n",push(sA,3)); return 0; }

4 个答案:

答案 0 :(得分:2)

因为您按值传递了两个指针(因此您实际上传递了指针的副本),请将初始化函数更改为int initilize(stack **s)并将s = newStack;更改为{{1然后调用初始化,如*s = newStack;

你真的不应该动态分配对象,除非你不必{i}你分配的内存,这是内存泄漏。

答案 1 :(得分:2)

当您将指针传递给函数时,该函数会收到指针的副本。这通常很好,除非您更改/创建指针的START地址

在您的情况下,sAsB不包含地址(当您将它们传递给initialize时,它们指向什么都没有)。因此,initialize函数必须使用指针的地址,而不是指针本身,以便为{{1}中可见的指针指定地址}。例如:

main

取消引用上面的双指针void initialize(stack **s) { stack *newStack; newStack = malloc(sizeof(*newStack)); newStack->count = 0; *s = newStack; } ... initialize (&sA); (例如**s),将*s = newStack;的地址指定为指针newStack的值。

我还建议在将s的位置分配给newStack之前检查分配是否成功:

*s

答案 2 :(得分:2)

我认为您需要以下内容

#include <stdio.h>

#define STACK_SIZE  5

typedef struct stackADT 
{
    int elements[STACK_SIZE];
    int count;
} stack;

void initialize( stack *s )
{
    s->count = 0;
}

int push( stack *s, int value )
{
    return s->count == STACK_SIZE ? -1 : ( s->elements[s->count++] = value );
}

int main(void) 
{
    stack sA;
    stack sB;

    initialize( &sA );
    initialize( &sB );

    printf( "%d\n", push( &sA, 3 ) );

    return 0;
}

答案 3 :(得分:0)

您正在接收分段错误,因为您试图将push()中的值分配给未分配的内存区域。 initialize()可以成功分配内存并使用count = 0对其进行初始化,但您对s = newStack的分配不起作用。正如大卫和亚历杭德罗指出的那样,你传递的是“指针的副本”。实质上,您传递的是未初始化的stack变量的地址,但是您没有通过该函数传递使用新地址更新该变量的方法。你需要传递一个指向堆栈指针的指针。 (也称为二级指针。)这意味着initialize()将接收保存堆栈结构的内存地址的变量的内存地址。因此,函数可以将二级指针的指针分配给malloced堆栈。

通过简单地查看代码可能更容易理解:

#define STACK_SIZE 5

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

typedef struct stackADT {
    int elements[STACK_SIZE];
    int count;
} stack;

void initialize(stack **s)
{
     stack *newStack;
     newStack = malloc(sizeof(*newStack));

     if(NULL == newStack){
        // Malloc could not allocate memory
        // for newStack.
        // Set s to NULL to indicate the error
        s = NULL;
        // Return prematurely
        return;
     } // else, malloc succeeded

     newStack->count = 0;

     // Assign the value of the malloced stack pointer to the pointee of stack **s
     *s = newStack;
}

int push(stack *s, int value)
{
    if( s->count == STACK_SIZE ){
        // Stack has too many elements.
        // Return with error value (-1)
        return -1;
    } else {
        // Assign the new value to the current last index
        s->elements[s->count] = value;
        // Add count to indicate a new variable has been added
        s->count++;
        // Use the array to return the value just added
        return s->elements[ (s->count - 1) ];
    }
}

int main()
{
    stack* sA;
    stack* sB;

    // Send the function a pointer to the stack pointer
    initialize(&sA);
    initialize(&sB);

    if(sA == NULL){
        puts("Could not allocate the memory for stack variable sA.\n");
        return -1;
    }

    printf("%d\n", push(sA, 3) );

    // Clean up the memory
    free(sA);
    free(sB);

    return 0;
}

我还稍微修改了代码,以便在value函数中拆分push()的分配,并添加了malloc()错误检查。

注意如果您对此感到满意,我建议您使用Vlad的推送功能。它更短更简洁;但是,它牺牲了可读性。由于您是初学者,我决定将其展开可能更容易理解。