指针变量和函数返回的地址之间有什么区别?

问题描述

下面的代码给我一个错误分段错误(核心已转储),但是如果我取消注释 return ptr 评论 return&newStack ,它将正常运行。 为什么会有所不同,如果我们考虑在函数中通过引用传递,则可以采用 function(&variable),这里我们不需要传递指针。我对此概念有些困惑。

    #include <stdio.h>
    #include <stdlib.h>
    
    typedef struct
    {
        int top;
        char arr[10];
    }Stack;
    
    Stack * create_stack(){
        Stack newStack,*ptr;
        newStack.top = -1;
        ptr = &newStack;
        
        //return ptr; 
        return &newStack;
    }
    
    int main(){
        Stack * S1;
        S1 = create_stack();
        printf("%d\n",S1->top);
        return 0;
    }

解决方法

为什么会有所不同

因为这是未定义行为的工作方式。基本上任何事情都可能发生,包括程序似乎运行正常。

返回指向局部变量的指针是未定义的行为。如果将newStack声明为static,则代码是有效的,但是应该有很好的理由返回指向本地堆栈变量的指针。在大多数情况下,这是不良设计的迹象。

returning a local variable from function in C

Undefined,unspecified and implementation-defined behavior

我将使用以下选项之一:

Stack * create_stack(){
    Stack *stack = malloc(sizeof *stack);
    // Outside the scope of the question,but error checking malloc
    // is a good habit
    if(stack)
        stack->top = -1;

    return stack;
}

int main(void)
{
    Stack *stack = create_stack();
    // Do work
    free(stack);
}

void create_stack(Stack *stack){
    stack->top = -1;
}

int main(void)
{
    Stack stack;
    create_stack(&stack);
    // Do work
    // No free required
}

取决于您是否要使用动态分配。

带有静态示例,您不应该这样做!

Stack * create_stack(){
    static Stack stack;
    stack.top = -1;
    return &stack;  // Valid,but very bad as seen below
}

int main(void)
{
    Stack *stack1 = create_stack();
    Stack *stack2 = create_stack();

    // Now stack1 and stack2 will point to THE SAME stack
}

上面的代码是有效的,但它可能不会执行您想要的操作。如果使用静态,则不能创建两个不同的堆栈。

,

函数返回时,newStack的地址空间不再有效。您可以这样做:

    Stack * create_stack(){
        Stack *ptr;
        static Stack newStack;
        newStack.top = -1;
        ptr = &newStack;
        
        //return ptr; 
        return &newStack;
    }