一个关于函数内部指针参数返回的错误调试及分析
来源:互联网 发布:昆明中药厂网络商学院 编辑:程序博客网 时间:2024/05/16 03:16
一个关于函数内部指针参数返回的错误调试及分析
在C语言中如下两个概念是非常重要,但又是极其容易在编程中出问题的:
1. C语言中指针存储的是一个地址,而非实际的数据项内容。
2. C语言中函数内部定义的变量的作用域或生存空间只在函数内。
下面就本人在编程中出现的一个错误代码进行分析,(这个代码出的问题就是以上2点。)除此之外提出一个gcc导致该程序费了很大功夫才找到这2个错误的bug。
01.#include<stdio.h>
02.#include<stdlib.h>
03.struct test{
04.int x;
05.int y;
06.};
07.struct test2{
08.int z;
09.struct test *w;
10.};
11.void fun(struct test2 *st)
12.{
13.struct test fst;
14.fst.x=1;
15.fst.y=2;
16.st->w=&fst;
17.printf("fun: %d %d /n",fst.x,fst.y);
18.}
19.
20.void print(struct test2 *st)
21.{
22.printf("print:%d %d/n",st->w->x,st->w->y);
23.}
24.
25.int main()
26.{
27.struct test2 *mst;
28.mst=(struct test2 *)calloc(1,sizeof(struct test2));
29.mst->w=(struct test *)calloc(1,sizeof(struct test));
30.fun(mst);
31.printf("main: %d %d/n",mst->w->x,mst->w->y);
32.print(mst);
33.return 0;
34.}
该代码的错误在于,16行处,将fun函数内的局部变量fst的地址交给了指针参数st->w,从而主函数中打印输出的时候st->w指针所指的内容由于fun函数的返回而被系统回收了。
现在看来原理非常简单。但调试该段代码却花费了本人很多时间。执行上面的程序我们得到如下的结果:
01.fun: 1 2
02.main: 1 2
03.print:2013480168 -1
在结果第1行返回正确的值1 2,并且在第2行,仍然返回的是1 2。这就让人搞不清楚了,由现在的输出怎么也不会让人联想到在fun函数里面就出了问题,因为在31行main函数中输出了正确的结果1 2,从而检查的焦点不自觉的就转移到32行调用的print函数。但该函数本来就没有任何错误,自然就陷入了麻烦之中了。
我们再看下面这个程序:
01.#include<stdio.h>
02.#include<stdlib.h>
03.struct test
04.{
05.int x;
06.int y;
07.};
08.
09.void fun(struct test *st)
10.{
11.struct test fst;
12.fst.x=1;
13.fst.y=2;
14.st=&fst;
15.printf("fun:%d %d/n",fst.x,fst.y);
16.}
17.int main()
18.{
19.struct test *mst;
20.mst=(struct test *)calloc(1,sizeof(struct test));
21.fun(mst);
22.printf("main:%d %d /n",mst->x,mst->y);
23.return 0;
24.}
同样的再14行fun函数中错误的将局部变量fst的地址给了参数指针,而主函数中该地址被系统回收,得到如下的结果:
01.fun:1 2
02.main:0 0
这个就比较明显的看出效果来,在fun函数返回后,main函数中输出的结果已经被清零了,说明fun函数部分有问题。
我们再回过头看看第一个代码,为什么会出现前面的状况,2个代码不同之处在于,第一个代码中结构体的成员本身也是指针,我们是对这个成员指针进行的操作,在fun返回后系统并没有对该成员引用的地址进行销毁(应该算是gcc的一个bug),所以在31行的main函数中返回的仍然是1 2,而32行调用print函数时,系统将保存当前的断点地址等信息,该信息恰好写入了原来fun函数分配的局部变量fst的地址,从而改变了原有的数据内容1 2,所以输出结果的第3行,得到了一个错误的结果。
- 一个关于函数内部指针参数返回的错误调试及分析
- C函数关于qsort最后一个函数指针参数指向的函数的返回值和升序排序的关系
- 可以返回函数内部定义的指针
- 关于函数返回值为指针类型的分析
- 关于函数返回值为指针类型的分析
- 关于函数返回值为指针类型的分析
- 关于函数的指针参数
- 关于函数的指针参数
- 返回函数的指针, 参数为函数指针。。。。。
- 声明一个函数,参数是一个char,返回值是指向一个int参数一个int返回值的函数指针
- 函数返回指针分析
- C++函数指针指向一个返回函数指针的函数
- 关于函数返回指针
- 关于函数指针的理解(指向的函数返回值又是另外一个函数指针)
- 关于static与返回指针的函数
- 关于指针变量,以及指针变量作为函数参数的题目分析
- 关于函数指针数组与返回数组指针的函数
- 关于函数指针数组与返回数组指针的函数
- SHGetSpecialFolderPath 一个很有用的API
- 和同事讨论如何同时管理多个项目的回复
- 龙象之争,从自由开始
- 学会孤独
- Linux Journal 2009年度读者选择奖出炉
- 一个关于函数内部指针参数返回的错误调试及分析
- Excel Data 导入oracle
- flex filereference+httphandler实现文件上传/下载
- 毕业在即,忙····
- 网站
- Flex与.NET互操作(一):基于Socket的网络连接
- 3大语言的比较
- sql使用命令(一)
- WEB Workers提升WEB前端脚本JavaScript的处理性能