问题描述
下面的代码给我一个错误分段错误(核心已转储),但是如果我取消注释 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;
}