免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: lsupper
打印 上一主题 下一主题

[C++] 找BUG拉..嘿嘿,大家来找找看哈... [复制链接]

论坛徽章:
0
31 [报告]
发表于 2012-11-06 11:44 |只看该作者
回复 27# lin5161678


    不好意思,上一个有些修改struct..{ int *p}//我改成了int p[10]
  1. [root@speedlinux ~]# gdb a.out
  2. GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2) 7.4-2012.04
  3. Copyright (C) 2012 Free Software Foundation, Inc.
  4. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
  5. This is free software: you are free to change and redistribute it.
  6. There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
  7. and "show warranty" for details.
  8. This GDB was configured as "i686-linux-gnu".
  9. For bug reporting instructions, please see:
  10. <http://bugs.launchpad.net/gdb-linaro/>...
  11. Reading symbols from /root/a.out...done.
  12. (gdb) list
  13. 4
  14. 5       using namespace std;
  15. 6
  16. 7       struct STEST {
  17. 8           int i;
  18. 9           int *p;
  19. 10      };
  20. 11
  21. 12      int main(void)
  22. 13      {
  23. (gdb)
  24. 14          struct STEST x;
  25. 15          int *p = &x.i;
  26. 16          p[0] = 4;
  27. 17          p[1] = 3;
  28. 18
  29. 19          string s1="test";
  30. 20          char msgBuffer[256]={0};
  31. 21          if(!s1.empty())
  32. 22             sprintf(msgBuffer, "s1:%s\n",s1.c_str());
  33. 23          x.p[0]=5;
  34. (gdb)
  35. 24          printf("msgBuffer%s,%d\n", msgBuffer, x.i,*x.p);
  36. 25          return 0;
  37. 26      }
  38. (gdb)
  39. Line number 27 out of range; test.c has 26 lines.
  40. (gdb) break 15
  41. Breakpoint 1 at 0x8048801: file test.c, line 15.
  42. (gdb) break 16
  43. Breakpoint 2 at 0x8048809: file test.c, line 16.
  44. (gdb) break 17
  45. Breakpoint 3 at 0x8048813: file test.c, line 17.
  46. (gdb) break 19
  47. Breakpoint 4 at 0x8048820: file test.c, line 19.
  48. (gdb) break 20
  49. Breakpoint 5 at 0x8048854: file test.c, line 20.
  50. (gdb) break 21
  51. Breakpoint 6 at 0x8048868: file test.c, line 21.
  52. (gdb) break 22
  53. Breakpoint 7 at 0x804887b: file test.c, line 22.
  54. (gdb) break 23
  55. Breakpoint 8 at 0x804889f: file test.c, line 23.
  56. (gdb) break 24
  57. Breakpoint 9 at 0x80488a9: file test.c, line 24.
  58. (gdb) run
  59. Starting program: /root/a.out

  60. Breakpoint 1, main () at test.c:15
  61. 15          int *p = &x.i;
  62. (gdb) p *p
  63. $1 = -1208203904
  64. (gdb) p x.i
  65. $2 = -1210944584
  66. (gdb) p &x.i
  67. $3 = (int *) 0xbffff398
  68. (gdb) p *x.p
  69. $4 = -1210974208
  70. (gdb) n

  71. Breakpoint 2, main () at test.c:16
  72. 16          p[0] = 4;
  73. (gdb) p p[0]
  74. $5 = -1210944584
  75. (gdb) p x.i
  76. $6 = -1210944584
  77. (gdb) n

  78. Breakpoint 3, main () at test.c:17
  79. 17          p[1] = 3;
  80. (gdb) p p[0]
  81. $7 = 4
  82. (gdb) p x.i
  83. $8 = 4
  84. (gdb) p p[1]
  85. $9 = -1209229312
  86. (gdb) p *x.p
  87. $10 = -1210974208
  88. (gdb) n

  89. Breakpoint 4, main () at test.c:19
  90. 19          string s1="test";
  91. (gdb) p *x.p
  92. Cannot access memory at address 0x3
  93. (gdb) p p[1]
  94. $11 = 3
  95. (gdb) p x.p[0]
  96. Cannot access memory at address 0x3
  97. (gdb) p x.p[1]
  98. Cannot access memory at address 0x7
  99. (gdb) n

  100. Breakpoint 5, main () at test.c:20
  101. 20          char msgBuffer[256]={0};
  102. (gdb) p msgBuffer[0]
  103. $12 = -42 '\326'
  104. (gdb) p msgBuffer[1]
  105. $13 = 10 '\n'
  106. (gdb) p msgBuffer[2]
  107. $14 = -8 '\370'
  108. (gdb) p msgBuffer[0]@256
  109. $15 = "\326\n\370\267\377\377\377\377,.\374\267\370K\374\267\000\000\000\000\334\363\377\277\364\357\377\267\030\371\377\267\001\000\000\000\000\000\000\000\213\302\376\267\320\372\377\267C0辗\001\000\000\000\001\000\000\000\000\000\000\000i,\365\267\244t\374\267\020u\374\267\200E\374\267\364_\354\267\000\000\000\000\001\000\000\000h\364\377\277\253\061辗\344c旆竤曳\000\000\000\000C0辗\001\000\000\000\226\061辗\364_\354\267%2辗\220\206\004\bP\240\004\bD\240\004\b\344c旆怽206\004\b\366\061辗\364\237\004\bn\211\004\b\220\206\004\bP\240\004\bD\240\004\b%2辗03\364\267\270\210\374\267\210\364\377\277\212\211\004\b\001\000\000\000\377\377\000\000\001\000\000\000\r\206\004\b\344c旆竆210\374\267\001\000\000\000\342\211\004\b\001\000\000\000T\365\377\277\\\365\377\277%2辗p\322\376\267\000\000\000\000\231\211\004\b"
  110. (gdb) n

  111. Breakpoint 6, main () at test.c:21
  112. 21          if(!s1.empty())
  113. (gdb) p msgBuffer[0]@256
  114. $16 = '\000' <repeats 255 times>
  115. (gdb) n

  116. Breakpoint 7, main () at test.c:22
  117. 22             sprintf(msgBuffer, "s1:%s\n",s1.c_str());
  118. (gdb) p msgBuffer[0]@256
  119. $17 = '\000' <repeats 255 times>
  120. (gdb) n

  121. Breakpoint 8, main () at test.c:23
  122. 23          x.p[0]=5;
  123. (gdb) p x.p[0]
  124. Cannot access memory at address 0x3
  125. (gdb) n

  126. Program received signal SIGSEGV, Segmentation fault.
  127. 0x080488a3 in main () at test.c:23
  128. 23          x.p[0]=5;
  129. (gdb) p x.p[0]
  130. Cannot access memory at address 0x3
  131. (gdb) p x.p[1]
  132. Cannot access memory at address 0x7
  133. (gdb) p p[1]  
  134. $18 = 3
  135. (gdb) p *x.p
  136. Cannot access memory at address 0x3
  137. (gdb) p msgBuffer, x.i,*x.p
  138. Cannot access memory at address 0x3
  139. (gdb) p msgBuffer
  140. $19 = "s1:test\n", '\000' <repeats 247 times>
  141. (gdb) p x.i
  142. $20 = 4
  143. (gdb) p *x.p
  144. Cannot access memory at address 0x3
  145. (gdb) quit
  146. A debugging session is active.

  147.         Inferior 1 [process 3458] will be killed.

  148. Quit anyway? (y or n) y
  149. [root@speedlinux ~]#
复制代码

论坛徽章:
0
32 [报告]
发表于 2012-11-06 12:41 |只看该作者
回复 30# lin5161678


   

论坛徽章:
1
摩羯座
日期:2013-12-19 10:04:07
33 [报告]
发表于 2012-11-06 12:44 |只看该作者
本帖最后由 lin5161678 于 2012-11-06 12:47 编辑

回复 32# FaintKnowledge

别光顾着笑呀
我说出我的看法了
哪里不对你就把反驳意见摆上来


   

论坛徽章:
0
34 [报告]
发表于 2012-11-06 14:03 |只看该作者
回复 30# lin5161678

你是不是特想抽我啊? 有机会吧,我保证不还手...

基本上你说的也都有道理,

未定义
我说的为定义根未初始化是一个意思...习惯了...这个我得改

int *p = &x.i;
你看他初始化声明指针p的形式是这样的,我觉得这个意思是将p指向了x.i的地址,当然是整型的,而且这个也验证了:
  1. (gdb) print &x.i
  2. $2 = (int *) 0xbffff398
  3. (gdb) print p
  4. $3 = (int *) 0xbffff398
复制代码
不知道这样理解是不是对的:对指针的操作就是移动

你说的
p[0] == *(p+0) == *p == x.i ///////////////////x.i=4 给一个int变量赋值
是这个意思确实没问题.
但如果是:*p = &x.i;p[0]=4;(直接这样赋值,也就是直接改变p的指向,不就是把一个指针弄弯吗?)
再者,
一开始他就定义了一个结构:
struct STEST {
    int i;
    int *p;
};
从数据结构上来讲,这就是个顺序表结构*p可以和数组相互转换的话.即使不能相互转换,那它也是个顺序表.无论如何它就是个顺序表.当然,这点除了最后printf..*x.p基本上没用到.
p[1] = 3;            //这个就没戏了吧??
,x被初始化了,*p = &x.i;p[0]=4;这个间接的调用了,从另一个角度出发,间接的对这个线形表赋值了.接着p[1]=3,这到这才是越界
Cannot access memory at address
,因为这和指针指向的内容不能被修改,,如果在顺序表中定义的是int p[SIZE],那么就不会越界,x.p[0]就会等于3,这个只有在p[1]写入缓存之后才能显示出来.

string 和char区别
我说的只是初始化数值时候的区别,我手贱,口误....我错了...


char msgBuffer[256] = {0};
,我当然知道是要所有的数组全部初始化为0,但调试的时候却是这样的:
  1. \326\n\370\267\377\377\377\377,.\374\267\370K\374\267\000\000\000\000\334\363\377\277\364\357\377\267\030\371\377\267\001\000\000\000\000\000\000\000\213\302\376\267\320\372\377\267C0辗\001\000\000\000\001\000\000\000\000\000\000\000i,\365\267\244t\374\267\020u\374\267\200E\374\267\364_\354\267\000\000\000\000\001\000\000\000h\364\377\277\253\061辗\344c旆竤曳\000\000\000\000C0辗\001\000\000\000\226\061辗\364_\354\267%2辗\220\206\004\bP\240\004\bD\240\004\b\344c旆怽206\004\b\366\061辗\364\237\004\bj\211\004\b\220\206\004\bP\240\004\bD\240\004\b%2辗03\364\267\270\210\374\267\210\364\377\277\206\211\004\b\001\000\000\000\377\377\000\000\001\000\000\000\r\206\004\b\344c旆竆210\374\267\001\000\000\000\342\211\004\b\001\000\000\000T\365\377\277\\\365\377\277%2辗p\322\376\267\000\000\000\000\231\211\004
复制代码
我是试了各种方法都不能全变为0呵,包括对每个元素进行赋值,new等,都不能把这段内存变为0,所以,我就那样认为了...这个以后再想办法吧...

你!!! 汗 x.p 有定义 你说 *x.p x.p指向的对象没定义这个说得过去 x的成员不可以修改这是什么说法 我的天 x的成员不可修改 要x做什么
这个不用这么纠结吧? char *p="test",*p能直接修改吗?

论坛徽章:
0
35 [报告]
发表于 2012-11-06 14:23 |只看该作者
本帖最后由 FaintKnowledge 于 2012-11-06 14:29 编辑

回复 33# lin5161678


    这里还有个这样说的:

http://bbs.chinaunix.net/thread-1777122-1-1.html

hellioncu 发表于 2010-09-01 09:35
char buf[128]={'0'};这样是全部初始化为0

论坛徽章:
1
摩羯座
日期:2013-12-19 10:04:07
36 [报告]
发表于 2012-11-06 14:28 |只看该作者
FaintKnowledge 发表于 2012-11-06 14:03
但如果是:*p = &x.i;p[0]=4;(直接这样赋值,也就是直接改变p的指向,不就是把一个指针弄弯吗?)

这里你理解错了 直接这样赋值 不会改变指针p的指向 p还是指向 x.i
接着p[1]=3,这到这才是越界

这个是越界 没疑问 但是显然你不知道他越界打算做什么 好吧 不知道也有好处 毕竟是错误的做法
因为这和指针指向的内容不能被修改

字符串字面量 和 char* 两者并不等同的 企图修改字符串字面量是一个未定义行为
然后 char* 指向的 不一定就必须是一个字符串字面量
char ch; char *p = &ch;
char str[10]; char *p = str;
char* p = malloc......
好多好多 都是能修改指针指向的内容

当然在LZ的代码 这个char* 干脆就是一个野指针
我当然知道是要所有的数组全部初始化为0,但调试的时候却是这样的

我不清楚你为什么会这样
我这边是这样的

论坛徽章:
1
摩羯座
日期:2013-12-19 10:04:07
37 [报告]
发表于 2012-11-06 14:32 |只看该作者
回复 35# FaintKnowledge

我很真诚的告诉你 继续向下看  
而且 你看到的那个哥们 是说错了的
char str[10] = {'0'};
是把第一个初始化为 48 其他的全部初始化为0
   

论坛徽章:
0
38 [报告]
发表于 2012-11-06 14:40 |只看该作者
回复 36# lin5161678


这个工具比较直观啊 ...我用的是gdb,你这个是什么啊?
看看这个算不算答案啊:http://bbs.chinaunix.net/thread-1777122-1-1.html

对指针的赋值标准的做法是先声明,后初始化对吧?
所以int *p = &x.i;应该是int *p ; p = &x.i;没错吧?int *p;这步应该最初是野指针,它有值吗?初始应该是这样的:p=0xb7784ff4,1727868
  1. #include "stdio.h"
  2. #include "stdlib.h"

  3. int main()
  4. {
  5.     int *p;
  6.         printf("%p,%d\n",p,*p);
  7. }
复制代码
所以,我说是改变了指针的指向.如果我所谓的标准的做法不成立,那这个也就不成立了...可恰好我调试使用的系统是32位的...

p[1]=3;这算越界吗?
把顺序表的*p改成p[];再分别查看x.p[1],p[1]试试,别的我还真没有到那境界...

论坛徽章:
0
39 [报告]
发表于 2012-11-06 14:41 |只看该作者
回复 37# lin5161678


    嗯,他这个肯定是错的...

论坛徽章:
0
40 [报告]
发表于 2012-11-06 14:45 |只看该作者
回复 26# FaintKnowledge


    我不知道我要怎么回复你,你看下@lin5161678兄弟的回复吧~~~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP