使用指针

时间:2018-02-13 14:42:51

标签: c pointers segmentation-fault

程序在推送功能方面没有问题,因为我可以到达结构的成员(例如密钥)。如果我调用push(stack,3),则在HEE上分配的newElem指针上的push函数中键为3,但是当它被分配给堆栈时使用,并且在push函数之外使用(在main中使用) ,它不再知道结构的成员在当前地址具有什么值。因此在我看来,malloc并没有真正起作用,并且没有将内存放在HEAP上,因为它不能再通过main函数访问了吗?

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

typedef struct list_element_t {
    int key;
    struct list_element_t* next;
    struct list_element_t* prev;

}ListElement;

ListElement* GetNewElement(int k) {
    ListElement* newElem = (ListElement*) malloc(sizeof(ListElement));
    newElem->key = k;
    newElem->next = NULL;
    newElem->prev = NULL;
    return newElem;
}

void push(ListElement* S, int k) {
    ListElement* newElem = GetNewElement(k);

    //The key is always correct here
    printf("%d\n", newElem->key);
    if(S == NULL) {
        S = newElem;
        //S is not NULL here.
        return;
    } 
    newElem->next = S;
    S->prev = newElem;
    //Put our stack in the back of the list
    S = newElem;

}

void display(ListElement* S) {
    ListElement* temp = S;
    while(temp != NULL) {
        printf("%d\n", temp->key);
        temp = temp->next;
    }
}

int main(int argc, char **argv)
{
    ListElement* stack = NULL;
    push(stack, 3);

    //stack is still NULL here????


    //Causes segmentation Fault
    printf("%d\n", stack->key);


    //Never prints anything (stack is NULL)
    display(stack);
    return 0;
}

1 个答案:

答案 0 :(得分:1)

S函数中的

push是局部变量,因此在此分配中

S = newElem;

newElem分配给push结束时销毁的临时对象。如果要修改S指向的内容,则应通过指向指针传递此内容。

void push(ListElement** S, int k) {
  ListElement* newElem = GetNewElement(k);

  printf("%d\n", newElem->key);
  if(*S == NULL) {
    *S = newElem;
    return;
  } 
  newElem->next = *S;
  (*S)->prev = newElem;
  *S = newElem;
}

并在main函数调用push中运行如下

  ListElement* stack = NULL;
  push(&stack, 3);