GodLordGee 发表于 2021-11-6 23:57:41

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

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

int main(void){
    char *p = NULL;
    char *num;
    p = (char *)(malloc(30 * sizeof(char)));
    printf("please input \n");
    fgets(p, 30, stdin);
    // gets(p);
    printf("%s", p);
    printf("%u", strlen(p));
    int lens = strlen(p);
    p = (char *)realloc(p, lens * sizeof(char));
    char temp = '0';
    for (int i = 0; i <= lens/2-1;i++){
      printf("--%c", p);
      putchar('\n');
      p = p;
      p = p;
      p = p ;
    }
    printf("****%s", p);
    printf("%u", strlen(p));
    return 0;
}
建议在第15行即realloc处打断点,在倒数第4行打断点,即 printf p处,这样可以在监视器看到p的值明显的不一样

人造人 发表于 2021-11-7 00:15:51

如果我使用了realloc,我发现,整个数组的长度就变成了24
你怎么知道变成了 24 ?

人造人 发表于 2021-11-7 00:18:13

还有,你这程序有问题,具体看报错信息
heap-buffer-overflow

$ cat main.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(void){
    char *p = NULL;
    char *num;
    p = (char *)(malloc(30 * sizeof(char)));
    printf("please input \n");
    fgets(p, 30, stdin);
    // gets(p);
    printf("%s", p);
    printf("%u", strlen(p));
    int lens = strlen(p);
    p = (char *)realloc(p, lens * sizeof(char));
    char temp = '0';
    for (int i = 0; i <= lens/2-1;i++){
      printf("--%c", p);
      putchar('\n');
      p = p;
      p = p;
      p = p ;
    }
    printf("****%s", p);
    printf("%u", strlen(p));
    return 0;
}
$ gcc-debug -o main main.c
main.c: In function ‘main’:
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=]
   13 |   printf("%u", strlen(p));
      |             ~^   ~~~~~~~~~
      |            |   |
      |            |   size_t {aka long unsigned int}
      |            unsigned int
      |             %lu
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=]
   25 |   printf("%u", strlen(p));
      |             ~^   ~~~~~~~~~
      |            |   |
      |            |   size_t {aka long unsigned int}
      |            unsigned int
      |             %lu
main.c:16:10: warning: unused variable ‘temp’ [-Wunused-variable]
   16 |   char temp = '0';
      |          ^~~~
main.c:7:11: warning: unused variable ‘num’ [-Wunused-variable]
    7 |   char *num;
      |         ^~~
$ ./main
please input
1234
1234
5--1
=================================================================
==25195==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000015 at pc 0x558191689597 bp 0x7ffeed2f55d0 sp 0x7ffeed2f55c0
WRITE of size 1 at 0x602000000015 thread T0
    #0 0x558191689596 in main /tmp/main.c:20
    #1 0x7fedd6d93b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
    #2 0x55819168918d in _start (/tmp/main+0x218d)

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

SUMMARY: AddressSanitizer: heap-buffer-overflow /tmp/main.c:20 in main
Shadow bytes around the buggy address:
0x0c047fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c047fff8000: fa fafa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable:         00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone:       fa
Freed heap region:       fd
Stack left redzone:      f1
Stack mid redzone:       f2
Stack right redzone:   f3
Stack after return:      f5
Stack use after scope:   f8
Global redzone:          f9
Global init order:       f6
Poisoned by user:      f7
Container overflow:      fc
Array cookie:            ac
Intra object redzone:    bb
ASan internal:         fe
Left alloca redzone:   ca
Right alloca redzone:    cb
Shadow gap:            cc
==25195==ABORTING
$

人造人 发表于 2021-11-7 00:27:52

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(void){
    char *p = NULL;
    //char *num;
    //p = (char *)(malloc(30 * sizeof(char)));
    p = malloc(30);
    //printf("please input \n");
    printf("please input: ");
    fgets(p, 30, stdin);
    // gets(p);
    printf("%s", p);
    //printf("%u", strlen(p));
    printf("%lu", strlen(p));
    int lens = strlen(p);
    //p = (char *)realloc(p, lens * sizeof(char));
    p = realloc(p, lens + 1);
    //char temp = '0';
    for (int i = 0; i <= lens/2-1;i++){
      printf("--%c", p);
      putchar('\n');

      //p = p;
      //p = p;
      //p = p ;
    }
    printf("****%s", p);
    //printf("%u", strlen(p));
    printf("%lu", strlen(p));
    free(p);
    return 0;
}

人造人 发表于 2021-11-7 00:32:42

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int main(void){
    char *p = NULL;
    //char *num;
    //p = (char *)(malloc(30 * sizeof(char)));
    p = malloc(30);
    //printf("please input \n");
    printf("please input: ");
    fgets(p, 30, stdin);
    // gets(p);
    printf("%s", p);
    //printf("%u", strlen(p));
    printf("%lu", strlen(p));
    int lens = strlen(p);
    //p = (char *)realloc(p, lens * sizeof(char));
    p = realloc(p, lens + 1);
    //char temp = '0';
    /*
    for (int i = 0; i <= lens/2-1;i++){
      printf("--%c", p);
      putchar('\n');

      // 这是做什么?
      //p = p;
      //p = p;
      //p = p ;
    }
    */
    int i = 0, j = lens - 2;
    while(i < j) {
      char temp = p;
      p = p;
      p = temp;
      ++i; --j;
    }
    printf("****%s", p);
    //printf("%u", strlen(p));
    //printf("%lu", strlen(p));
    printf("%lu\n", strlen(p));
    free(p);
    return 0;
}

GodLordGee 发表于 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�\376\253\253\253\253\253\253\253\253\253\253\253\253\253\253\253", <incomplete sequence \376>

请问,是我使用realloc的用法用错了吗?

人造人 发表于 2021-11-7 00:41:21

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

对,看最后一个代码,给你改好了
页: [1]
查看完整版本: realloc函数使用后数据异常的问题