鱼C论坛

 找回密码
 立即注册
12
返回列表 发新帖
楼主: 投入就放过

c 语言 scanf函数的使用

[复制链接]
发表于 2022-3-6 14:29:39 | 显示全部楼层
傻眼貓咪 发表于 2022-3-6 12:31

可以知道用的是什么编译器吗?我想找这种超级敏感,报错多多的编译器学习学习

其实gcc就自带了内存检查的功能(运行时检查),只是默认没有开启
当然,要你的gcc是新版本的,旧版本的gcc有可能用不了
我不知道gcc从哪一个版本开始添加的内存检查功能,也不关心
反正我的gcc是新版本的,可以用内存检查,^_^
  1. $ gcc --version
  2. gcc (GCC) 11.2.0
  3. Copyright (C) 2021 Free Software Foundation, Inc.
  4. This is free software; see the source for copying conditions.  There is NO
  5. warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

  6. $
复制代码


谈不上最新,但是够用
我没有在windows中尝试过gcc的内存检查功能,可能也能用?不知道


  1. $ cat main.c
  2. #include <stdio.h>
  3. #include <stdlib.h>

  4. int main(void) {
  5.     int *p = malloc(sizeof(*p));
  6.     *p = 123;
  7.     printf("%d\n", *p);
  8.     //free(p);
  9.     return 0;
  10. }
  11. $ gcc -g -Wall -fsanitize=undefined -fsanitize=leak -fsanitize=address -fno-omit-frame-pointer -o main main.c
  12. $ ./main
  13. 123

  14. =================================================================
  15. ==987243==ERROR: LeakSanitizer: detected memory leaks

  16. Direct leak of 4 byte(s) in 1 object(s) allocated from:
  17.     #0 0x7ff146f8cdd9 in __interceptor_malloc /usr/src/debug/gcc/libsanitizer/asan/asan_malloc_linux.cpp:145
  18.     #1 0x560d4f9611ba in main /tmp/C/main.c:5
  19.     #2 0x7ff14638330f in __libc_start_call_main (/usr/lib/libc.so.6+0x2d30f)

  20. SUMMARY: AddressSanitizer: 4 byte(s) leaked in 1 allocation(s).
  21. $ vim main.c
  22. $ cat main.c
  23. #include <stdio.h>
  24. #include <stdlib.h>

  25. int main(void) {
  26.     int *p = malloc(sizeof(*p));
  27.     *p = 123;
  28.     printf("%d\n", *p);
  29.     free(p);
  30.     return 0;
  31. }
  32. $ gcc -g -Wall -fsanitize=undefined -fsanitize=leak -fsanitize=address -fno-omit-frame-pointer -o main main.c
  33. $ ./main
  34. 123
  35. $
复制代码



  1. $ cat main.c
  2. #include <stdio.h>
  3. #include <stdlib.h>

  4. int main(void) {
  5.     int array[10] = {0};
  6.     int n;
  7.     scanf("%d", &n);
  8.     printf("%d\n", array[n]);
  9.     return 0;
  10. }
  11. $ gcc -g -Wall -fsanitize=undefined -fsanitize=leak -fsanitize=address -fno-omit-frame-pointer -o main main.c
  12. $ ./main
  13. 10
  14. main.c:8:25: runtime error: index 10 out of bounds for type 'int [10]'
  15. main.c:8:5: runtime error: load of address 0x7ffdd3b78528 with insufficient space for an object of type 'int'
  16. 0x7ffdd3b78528: note: pointer points here
  17. 00 00 00 00  00 a6 3c 78 98 8a 28 12  c0 84 b7 d3 fd 7f 00 00  c0 7a fa 5c bf 7f 00 00  41 00 00 00
  18.               ^
  19. =================================================================
  20. ==988335==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffdd3b78528 at pc 0x55c36c0db465 bp 0x7ffdd3b784c0 sp 0x7ffdd3b784b0
  21. READ of size 4 at 0x7ffdd3b78528 thread T0
  22.     #0 0x55c36c0db464 in main /tmp/C/main.c:8
  23.     #1 0x7fbf5ba2030f in __libc_start_call_main (/usr/lib/libc.so.6+0x2d30f)
  24.     #2 0x7fbf5ba203c0 in __libc_start_main@GLIBC_2.2.5 (/usr/lib/libc.so.6+0x2d3c0)
  25.     #3 0x55c36c0db124 in _start (/tmp/C/main+0x1124)

  26. Address 0x7ffdd3b78528 is located in stack of thread T0 at offset 88 in frame
  27.     #0 0x55c36c0db208 in main /tmp/C/main.c:4

  28.   This frame has 2 object(s):
  29.     [32, 36) 'n' (line 6)
  30.     [48, 88) 'array' (line 5) <== Memory access at offset 88 overflows this variable
  31. HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
  32.       (longjmp and C++ exceptions *are* supported)
  33. SUMMARY: AddressSanitizer: stack-buffer-overflow /tmp/C/main.c:8 in main
  34. Shadow bytes around the buggy address:
  35.   0x10003a767050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  36.   0x10003a767060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  37.   0x10003a767070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  38.   0x10003a767080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  39.   0x10003a767090: 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1 04 f2
  40. =>0x10003a7670a0: 00 00 00 00 00[f3]f3 f3 f3 f3 00 00 00 00 00 00
  41.   0x10003a7670b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  42.   0x10003a7670c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  43.   0x10003a7670d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  44.   0x10003a7670e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  45.   0x10003a7670f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  46. Shadow byte legend (one shadow byte represents 8 application bytes):
  47.   Addressable:           00
  48.   Partially addressable: 01 02 03 04 05 06 07
  49.   Heap left redzone:       fa
  50.   Freed heap region:       fd
  51.   Stack left redzone:      f1
  52.   Stack mid redzone:       f2
  53.   Stack right redzone:     f3
  54.   Stack after return:      f5
  55.   Stack use after scope:   f8
  56.   Global redzone:          f9
  57.   Global init order:       f6
  58.   Poisoned by user:        f7
  59.   Container overflow:      fc
  60.   Array cookie:            ac
  61.   Intra object redzone:    bb
  62.   ASan internal:           fe
  63.   Left alloca redzone:     ca
  64.   Right alloca redzone:    cb
  65.   Shadow gap:              cc
  66. ==988335==ABORTING
  67. $
  68. $
  69. $
  70. $
  71. $
  72. $
  73. $ vim main.c
  74. $ cat main.c
  75. #include <stdio.h>
  76. #include <stdlib.h>

  77. int main(void) {
  78.     int array[10] = {0};
  79.     int n;
  80.     scanf("%d", &n);
  81.     array[n] = 123;
  82.     //printf("%d\n", array[n]);
  83.     return 0;
  84. }
  85. $ gcc -g -Wall -fsanitize=undefined -fsanitize=leak -fsanitize=address -fno-omit-frame-pointer -o main main.c
  86. main.c: In function ‘main’:
  87. main.c:5:9: warning: variable ‘array’ set but not used [-Wunused-but-set-variable]
  88.     5 |     int array[10] = {0};
  89.       |         ^~~~~
  90. $ ./main
  91. 10
  92. main.c:8:10: runtime error: index 10 out of bounds for type 'int [10]'
  93. main.c:8:14: runtime error: store to address 0x7ffec538b1b8 with insufficient space for an object of type 'int'
  94. 0x7ffec538b1b8: note: pointer points here
  95. 00 00 00 00  00 66 e4 ec 51 d5 04 37  50 b1 38 c5 fe 7f 00 00  c0 4a 7a 7c eb 7f 00 00  41 00 00 00
  96.               ^
  97. =================================================================
  98. ==988793==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffec538b1b8 at pc 0x55d75b226465 bp 0x7ffec538b150 sp 0x7ffec538b140
  99. WRITE of size 4 at 0x7ffec538b1b8 thread T0
  100.     #0 0x55d75b226464 in main /tmp/C/main.c:8
  101.     #1 0x7feb7b21d30f in __libc_start_call_main (/usr/lib/libc.so.6+0x2d30f)
  102.     #2 0x7feb7b21d3c0 in __libc_start_main@GLIBC_2.2.5 (/usr/lib/libc.so.6+0x2d3c0)
  103.     #3 0x55d75b226124 in _start (/tmp/C/main+0x1124)

  104. Address 0x7ffec538b1b8 is located in stack of thread T0 at offset 88 in frame
  105.     #0 0x55d75b226208 in main /tmp/C/main.c:4

  106.   This frame has 2 object(s):
  107.     [32, 36) 'n' (line 6)
  108.     [48, 88) 'array' (line 5) <== Memory access at offset 88 overflows this variable
  109. HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
  110.       (longjmp and C++ exceptions *are* supported)
  111. SUMMARY: AddressSanitizer: stack-buffer-overflow /tmp/C/main.c:8 in main
  112. Shadow bytes around the buggy address:
  113.   0x100058a695e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  114.   0x100058a695f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  115.   0x100058a69600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  116.   0x100058a69610: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  117.   0x100058a69620: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
  118. =>0x100058a69630: 04 f2 00 00 00 00 00[f3]f3 f3 f3 f3 00 00 00 00
  119.   0x100058a69640: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  120.   0x100058a69650: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  121.   0x100058a69660: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  122.   0x100058a69670: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  123.   0x100058a69680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  124. Shadow byte legend (one shadow byte represents 8 application bytes):
  125.   Addressable:           00
  126.   Partially addressable: 01 02 03 04 05 06 07
  127.   Heap left redzone:       fa
  128.   Freed heap region:       fd
  129.   Stack left redzone:      f1
  130.   Stack mid redzone:       f2
  131.   Stack right redzone:     f3
  132.   Stack after return:      f5
  133.   Stack use after scope:   f8
  134.   Global redzone:          f9
  135.   Global init order:       f6
  136.   Poisoned by user:        f7
  137.   Container overflow:      fc
  138.   Array cookie:            ac
  139.   Intra object redzone:    bb
  140.   ASan internal:           fe
  141.   Left alloca redzone:     ca
  142.   Right alloca redzone:    cb
  143.   Shadow gap:              cc
  144. ==988793==ABORTING
  145. $
复制代码


你可能会发现,我有时候用的编译命令是这样的
  1. gcc-debug -o main main.c
复制代码


这个 gcc-debug 其实是一个 alias
  1. alias gcc-debug='gcc -g -Wall -fsanitize=undefined -fsanitize=leak -fsanitize=address -fno-omit-frame-pointer'
复制代码


其实下面这两个是一样的
  1. gcc-debug -o main main.c
复制代码
  1. $ gcc -g -Wall -fsanitize=undefined -fsanitize=leak -fsanitize=address -fno-omit-frame-pointer -o main main.c
复制代码


我为了避免每一次编译代码都输入那么一长串,就弄了一个alias

这个报错的内容可以说是很详细了,代码的哪一行,变量的值,堆栈的当前状态
这些都给你列出来了,对debug非常有帮助
大部分的逻辑问题(逻辑错误),gcc的运行时检查都能检查出来
大部分的语法问题(语法错误),gcc的-Wall选项也全都给你指出来了
所以,写的代码很难出问题吧?
还有,其实我这边的报错是彩色的,看起来更舒服,^_^

1.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-3-6 14:34:04 | 显示全部楼层
  1. $ alias gcc-debug
  2. alias gcc-debug='gcc -g -Wall -fsanitize=undefined -fsanitize=leak -fsanitize=address -fno-omit-frame-pointer'
  3. $ cat main.c
  4. #include <stdio.h>
  5. #include <stdlib.h>

  6. int main(void) {
  7.     int array[10] = {0};
  8.     int n;
  9.     scanf("%d", &n);
  10.     array[n] = 123;
  11.     //printf("%d\n", array[n]);
  12.     return 0;
  13. }
  14. $ ls
  15. main  main.c
  16. $ rm main
  17. $ ls
  18. main.c
  19. $ gcc-debug -o main main.c
  20. main.c: In function ‘main’:
  21. main.c:5:9: warning: variable ‘array’ set but not used [-Wunused-but-set-variable]
  22.     5 |     int array[10] = {0};
  23.       |         ^~~~~
  24. $ ./main
  25. 13
  26. main.c:8:10: runtime error: index 13 out of bounds for type 'int [10]'
  27. main.c:8:14: runtime error: store to address 0x7ffcc7b9b984 with insufficient space for an object of type 'int'
  28. 0x7ffcc7b9b984: note: pointer points here
  29.   10 b9 b9 c7 fc 7f 00 00  c0 5a 67 e2 00 7f 00 00  41 00 00 00 60 60 00 00  3c e1 27 e1 00 7f 00 00
  30.               ^
  31. =================================================================
  32. ==989484==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffcc7b9b984 at pc 0x559bea5db465 bp 0x7ffcc7b9b910 sp 0x7ffcc7b9b900
  33. WRITE of size 4 at 0x7ffcc7b9b984 thread T0
  34.     #0 0x559bea5db464 in main /tmp/C/main.c:8
  35.     #1 0x7f00e10ee30f in __libc_start_call_main (/usr/lib/libc.so.6+0x2d30f)
  36.     #2 0x7f00e10ee3c0 in __libc_start_main@GLIBC_2.2.5 (/usr/lib/libc.so.6+0x2d3c0)
  37.     #3 0x559bea5db124 in _start (/tmp/C/main+0x1124)

  38. Address 0x7ffcc7b9b984 is located in stack of thread T0 at offset 100 in frame
  39.     #0 0x559bea5db208 in main /tmp/C/main.c:4

  40.   This frame has 2 object(s):
  41.     [32, 36) 'n' (line 6)
  42.     [48, 88) 'array' (line 5) <== Memory access at offset 100 overflows this variable
  43. HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
  44.       (longjmp and C++ exceptions *are* supported)
  45. SUMMARY: AddressSanitizer: stack-buffer-overflow /tmp/C/main.c:8 in main
  46. Shadow bytes around the buggy address:
  47.   0x100018f6b6e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  48.   0x100018f6b6f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  49.   0x100018f6b700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  50.   0x100018f6b710: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  51.   0x100018f6b720: 00 00 00 00 f1 f1 f1 f1 04 f2 00 00 00 00 00 f3
  52. =>0x100018f6b730:[f3]f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
  53.   0x100018f6b740: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  54.   0x100018f6b750: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  55.   0x100018f6b760: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  56.   0x100018f6b770: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  57.   0x100018f6b780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  58. Shadow byte legend (one shadow byte represents 8 application bytes):
  59.   Addressable:           00
  60.   Partially addressable: 01 02 03 04 05 06 07
  61.   Heap left redzone:       fa
  62.   Freed heap region:       fd
  63.   Stack left redzone:      f1
  64.   Stack mid redzone:       f2
  65.   Stack right redzone:     f3
  66.   Stack after return:      f5
  67.   Stack use after scope:   f8
  68.   Global redzone:          f9
  69.   Global init order:       f6
  70.   Poisoned by user:        f7
  71.   Container overflow:      fc
  72.   Array cookie:            ac
  73.   Intra object redzone:    bb
  74.   ASan internal:           fe
  75.   Left alloca redzone:     ca
  76.   Right alloca redzone:    cb
  77.   Shadow gap:              cc
  78. ==989484==ABORTING
  79. $
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-3-6 14:46:19 | 显示全部楼层


我的 gcc 报错机制可能如你所说的没有开启吧,每次我都要设断点才能查看我的内存,哈哈
没有关系,我已经下载 Clang 插件了,随时可以更换 Clang 或 gcc。
Clang 测试成功
01.jpg 02.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-3-6 14:56:20 | 显示全部楼层
傻眼貓咪 发表于 2022-3-6 14:46
我的 gcc 报错机制可能如你所说的没有开启吧,每次我都要设断点才能查看我的内存,哈哈 。
...

windows就不知道了,我没有在windows中用过gcc的内存检查
换linux吧,^_^
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-22 21:18

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表