鱼C论坛

 找回密码
 立即注册
查看: 2092|回复: 6

realloc函数使用后数据异常的问题

[复制链接]
发表于 2021-11-6 23:57:41 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
想实现一个数组倒序的函数,主要是为了检验realloc、malloc函数的使用,但是在使用中发现,如果使用malloc,将输入的值赋给指针,值是没有问题,使用strlen以及监视器查看,数据是正确的。例如,我输入的是 12,输出的长度是3(因为我用的是fgets,所以会把\n也存进去),但是,如果我使用了realloc,我发现,整个数组的长度就变成了24,在\n后面填充了大量无效数据,这到底是怎么回事呢?
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>

  4. int main(void){
  5.     char *p = NULL;
  6.     char *num;
  7.     p = (char *)(malloc(30 * sizeof(char)));
  8.     printf("please input \n");
  9.     fgets(p, 30, stdin);
  10.     // gets(p);
  11.     printf("%s", p);
  12.     printf("%u", strlen(p));
  13.     int lens = strlen(p);
  14.     p = (char *)realloc(p, lens * sizeof(char));
  15.     char temp = '0';
  16.     for (int i = 0; i <= lens/2-1;i++){
  17.         printf("--%c", p[i]);
  18.         putchar('\n');
  19.         p[lens] = p[lens -2 - i];
  20.         p[lens - 2 - i] = p[i];
  21.         p[i] = p [lens];
  22.     }
  23.     printf("****%s", p);
  24.     printf("%u", strlen(p));
  25.     return 0;
  26. }
复制代码

建议在第15行即realloc处打断点,在倒数第4行打断点,即 printf p处,这样可以在监视器看到p的值明显的不一样
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-11-7 00:15:51 | 显示全部楼层
如果我使用了realloc,我发现,整个数组的长度就变成了24
你怎么知道变成了 24 ?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-7 00:18:13 | 显示全部楼层
还有,你这程序有问题,具体看报错信息
heap-buffer-overflow

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

  5. int main(void){
  6.     char *p = NULL;
  7.     char *num;
  8.     p = (char *)(malloc(30 * sizeof(char)));
  9.     printf("please input \n");
  10.     fgets(p, 30, stdin);
  11.     // gets(p);
  12.     printf("%s", p);
  13.     printf("%u", strlen(p));
  14.     int lens = strlen(p);
  15.     p = (char *)realloc(p, lens * sizeof(char));
  16.     char temp = '0';
  17.     for (int i = 0; i <= lens/2-1;i++){
  18.         printf("--%c", p[i]);
  19.         putchar('\n');
  20.         p[lens] = p[lens -2 - i];
  21.         p[lens - 2 - i] = p[i];
  22.         p[i] = p [lens];
  23.     }
  24.     printf("****%s", p);
  25.     printf("%u", strlen(p));
  26.     return 0;
  27. }
  28. $ gcc-debug -o main main.c
  29. main.c: In function ‘main’:
  30. main.c:13:14: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘size_t’ {aka ‘long unsigned int’} [-Wformat=]
  31.    13 |     printf("%u", strlen(p));
  32.       |             ~^   ~~~~~~~~~
  33.       |              |   |
  34.       |              |   size_t {aka long unsigned int}
  35.       |              unsigned int
  36.       |             %lu
  37. main.c:25:14: warning: format ‘%u’ expects argument of type ‘unsigned int’, but argument 2 has type ‘size_t’ {aka ‘long unsigned int’} [-Wformat=]
  38.    25 |     printf("%u", strlen(p));
  39.       |             ~^   ~~~~~~~~~
  40.       |              |   |
  41.       |              |   size_t {aka long unsigned int}
  42.       |              unsigned int
  43.       |             %lu
  44. main.c:16:10: warning: unused variable ‘temp’ [-Wunused-variable]
  45.    16 |     char temp = '0';
  46.       |          ^~~~
  47. main.c:7:11: warning: unused variable ‘num’ [-Wunused-variable]
  48.     7 |     char *num;
  49.       |           ^~~
  50. $ ./main
  51. please input
  52. 1234
  53. 1234
  54. 5--1
  55. =================================================================
  56. ==25195==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000015 at pc 0x558191689597 bp 0x7ffeed2f55d0 sp 0x7ffeed2f55c0
  57. WRITE of size 1 at 0x602000000015 thread T0
  58.     #0 0x558191689596 in main /tmp/main.c:20
  59.     #1 0x7fedd6d93b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
  60.     #2 0x55819168918d in _start (/tmp/main+0x218d)

  61. 0x602000000015 is located 0 bytes to the right of 5-byte region [0x602000000010,0x602000000015)
  62. allocated by thread T0 here:
  63.     #0 0x7fedd7961652 in __interceptor_realloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cpp:164
  64.     #1 0x558191689352 in main /tmp/main.c:15
  65.     #2 0x7fedd6d93b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)

  66. SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/main.c:20 in main
  67. Shadow bytes around the buggy address:
  68.   0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  69.   0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  70.   0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  71.   0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  72.   0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  73. =>0x0c047fff8000: fa fa[05]fa fa fa fa fa fa fa fa fa fa fa fa fa
  74.   0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  75.   0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  76.   0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  77.   0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  78.   0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  79. Shadow byte legend (one shadow byte represents 8 application bytes):
  80.   Addressable:           00
  81.   Partially addressable: 01 02 03 04 05 06 07
  82.   Heap left redzone:       fa
  83.   Freed heap region:       fd
  84.   Stack left redzone:      f1
  85.   Stack mid redzone:       f2
  86.   Stack right redzone:     f3
  87.   Stack after return:      f5
  88.   Stack use after scope:   f8
  89.   Global redzone:          f9
  90.   Global init order:       f6
  91.   Poisoned by user:        f7
  92.   Container overflow:      fc
  93.   Array cookie:            ac
  94.   Intra object redzone:    bb
  95.   ASan internal:           fe
  96.   Left alloca redzone:     ca
  97.   Right alloca redzone:    cb
  98.   Shadow gap:              cc
  99. ==25195==ABORTING
  100. $
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-7 00:27:52 | 显示全部楼层
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>

  4. int main(void){
  5.     char *p = NULL;
  6.     //char *num;
  7.     //p = (char *)(malloc(30 * sizeof(char)));
  8.     p = malloc(30);
  9.     //printf("please input \n");
  10.     printf("please input: ");
  11.     fgets(p, 30, stdin);
  12.     // gets(p);
  13.     printf("%s", p);
  14.     //printf("%u", strlen(p));
  15.     printf("%lu", strlen(p));
  16.     int lens = strlen(p);
  17.     //p = (char *)realloc(p, lens * sizeof(char));
  18.     p = realloc(p, lens + 1);
  19.     //char temp = '0';
  20.     for (int i = 0; i <= lens/2-1;i++){
  21.         printf("--%c", p[i]);
  22.         putchar('\n');

  23.         //p[lens] = p[lens -2 - i];
  24.         //p[lens - 2 - i] = p[i];
  25.         //p[i] = p [lens];
  26.     }
  27.     printf("****%s", p);
  28.     //printf("%u", strlen(p));
  29.     printf("%lu", strlen(p));
  30.     free(p);
  31.     return 0;
  32. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-7 00:32:42 | 显示全部楼层
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <string.h>

  4. int main(void){
  5.     char *p = NULL;
  6.     //char *num;
  7.     //p = (char *)(malloc(30 * sizeof(char)));
  8.     p = malloc(30);
  9.     //printf("please input \n");
  10.     printf("please input: ");
  11.     fgets(p, 30, stdin);
  12.     // gets(p);
  13.     printf("%s", p);
  14.     //printf("%u", strlen(p));
  15.     printf("%lu", strlen(p));
  16.     int lens = strlen(p);
  17.     //p = (char *)realloc(p, lens * sizeof(char));
  18.     p = realloc(p, lens + 1);
  19.     //char temp = '0';
  20.     /*
  21.     for (int i = 0; i <= lens/2-1;i++){
  22.         printf("--%c", p[i]);
  23.         putchar('\n');

  24.         // 这是做什么?
  25.         //p[lens] = p[lens -2 - i];
  26.         //p[lens - 2 - i] = p[i];
  27.         //p[i] = p [lens];
  28.     }
  29.     */
  30.     int i = 0, j = lens - 2;
  31.     while(i < j) {
  32.         char temp = p[i];
  33.         p[i] = p[j];
  34.         p[j] = temp;
  35.         ++i; --j;
  36.     }
  37.     printf("****%s", p);
  38.     //printf("%u", strlen(p));
  39.     //printf("%lu", strlen(p));
  40.     printf("%lu\n", strlen(p));
  41.     free(p);
  42.     return 0;
  43. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-7 00:38:50 | 显示全部楼层
人造人 发表于 2021-11-7 00:18
还有,你这程序有问题,具体看报错信息
heap-buffer-overflow

感谢您的回复!可是我看不懂。。。我想知道的是,我在上面使用了malloc以后,在下面紧接着就使用了realloc,可是打了断点以后我发现realloc一执行完以后,指针p里面的数据就变了
没运行realloc之前,p的值是:0xe4840 "12\n"
运行realloc以后,p的值是:0xe4840 "12\n\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253\272\r\272\r&#65533;\376\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253", <incomplete sequence \376>

请问,是我使用realloc的用法用错了吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-7 00:41:21 | 显示全部楼层
GodLordGee 发表于 2021-11-7 00:38
感谢您的回复!可是我看不懂。。。我想知道的是,我在上面使用了malloc以后,在下面紧接着就使用了reallo ...

对,看最后一个代码,给你改好了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-25 20:19

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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