简体   繁体   English

为什么这会导致 C 中的分段错误

[英]Why does this lead to an segmentation fault in C

I try to put my pointer to the parameter passed it, but it leads to a segmentation fault我试图把我的指针指向传递给它的参数,但它导致了分段错误

#include <stdio.h>

void putPointer ( int *point, int num ) {
    point = &num;
}

int main(void) {

    int a = 42;

    int *p;
    // p = &a
    putPointer( p, a );

    printf( "%d\n", *p );

    return 0;
}

Arguments in C are copies of what are passed, so p in the main() function remains uninitialized after putPointer(p,a); C 中的 Arguments 是传递的内容的副本,因此main()中的p function 在putPointer(p,a); . . Using values of uninitialized non-static local variables, which are indeterminate, invokes undefined behavior .使用不确定的未初始化非静态局部变量的值会调用未定义的行为

Also note that you shouldn't take out pointers to non-static local variables (including function arguments) on returning from functions and must not use these pointers after returning from functions because non-static local variables are invalidated on returning.另请注意,从函数返回时不应取出指向非静态局部变量(包括 function 参数)的指针,并且在从函数返回后不得使用这些指针,因为非静态局部变量在返回时无效。

In putPointer() you try to assign point but point is a copy of p , thus p is left unchanged.putPointer()您尝试分配pointpointp副本,因此p保持不变。 Since p is still not initialised, it could access any address and *p causes a seg-fault.由于p仍未初始化,它可以访问任何地址并且*p会导致 seg-fault。

You could actually change p by expecting int **point_ptr as parameter, passing &p and performing *point_ptr=&num;您实际上可以通过期望int **point_ptr作为参数、传递&p并执行*point_ptr=&num;来更改p but you would encounter another problem.但你会遇到另一个问题。 Actually, num will disappear as soon as the function returns, so keeping its address in p is incorrect: num does not exist anymore when using *p .实际上,一旦 function 返回, num就会消失,因此将其地址保留在p中是不正确的:使用*pnum不再存在。

&num

will be the address of num on the stack .将是堆栈上 num 的地址。 You are trying dereference the stack in printf("%d\n", *p);您正在尝试取消引用printf("%d\n", *p); . .

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM