在外网看到一个比较好玩的问题,一下没反应过来。

2021-11-01 17:18:59 +08:00
 ReputationZh
#include <stdio.h>

int a = 12345;

void test(int *temp)
{
    temp = &a;
}

int main(int argc, char const *argv[])
{

    int *b = NULL;

    test(b);

    printf("%d\n",  a);
    printf("%d\n", *b);

    return 0;
}

return

12345    
Segmentation fault    

为什么段错误呢?

3867 次点击
所在节点    C
14 条回复
AoEiuV020
2021-11-01 17:24:24 +08:00
这不是老生常谈的传值传引用的问题么,c 语言入门书应该都有强调这些问题吧,
fkdog
2021-11-01 17:29:48 +08:00
test()里 temp 只是一个形参,
ReputationZh
2021-11-01 17:43:41 +08:00
@fkdog 这个解释可以
Hallelu
2021-11-01 17:45:07 +08:00
temp = &a; 并没有改变 b 的指向
ch2
2021-11-01 17:49:56 +08:00
test(b);//这一行不起任何作用
ryd994
2021-11-01 18:02:13 +08:00
把书看懂 || gdb 里跑一趟
这两样你做了任一样就不会有这个问题
gdb 里跑一圈就明白的事
CreSim
2021-11-01 18:08:33 +08:00
显然你需要传指针的指针。
ligiggy
2021-11-01 18:16:11 +08:00
temp 是形参。因为传递的是 null ,要想赋值,可以传递 指针的指针,然后 new 一个对象同时赋值即可

传入 int **temp ,然后赋值为*temp = new int(a);
0Vincent0Zhang0
2021-11-01 19:02:51 +08:00
int a = 12345 //申请一个存放 int 的盒子
int *b = NULL //申请了一个存放 int 盒子位置的 b 盒子,盒子里面放着 0 这个值
test(b) //把 b 盒子的内容 0 传给 test
// 进入 test 后 temp = b 盒子的内容,就是 0
temp = &a //把 a 盒子的位置传给 temp
printf("%d\n", a); //打印 a 盒子的内容
printf("%d\n", *b); //打印 b 盒子内容 0 所指向的盒子里面的内容,因为访问不到 0 位置的盒子内容,所以报错了。

在这里,test 无法改变 b 盒子的内容,因为传给 test 的只是 b 盒子的内容,而要改变 b 盒子的内容则需要传 b 盒子的位置。

例如这样改:
void test(int **temp){ *temp = &a }
test(&b);
Jooooooooo
2021-11-01 19:26:06 +08:00
temp 变了啊
Brian1900
2021-11-01 22:17:48 +08:00
想要修改一级指针的值,需要将函数参数修改为二级指针,否则函数将拷贝一份新的一级指针,修改的是新指针的值而不是 b 的值
anzu
2021-11-02 10:53:33 +08:00
把指针全去了,就不影响理解了,b 还是 b 。所以很多语言表面上都隐藏了指针的概念。
GrayXu
2021-11-02 11:21:51 +08:00
《大一 C 语言课程》
Kasumi20
2022-04-26 16:34:57 +08:00
访问内存 0x0000000000000000 ,能不段错误吗?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/812204

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX