【问题标题】:2d dynamic array of strings realloc causing error二维动态字符串数组重新分配导致错误
【发布时间】:2015-06-23 16:27:45
【问题描述】:

所以我试图重新分配一个 2d 字符数组,但它一直失败 我有 stdlib.h 包括在内,我仍然尝试使用强制转换以防万一,但出现了同样的错误。 我认为错误是我写的时候(使用strcpy

这实际上只是一个辅助测试程序,因为我无法获得另一个处理不断增长的二维数组的程序。当我strcpy

时出现段错误
int main()
{
  char** rec = malloc(10* sizeof(char*));;
  char** arr = malloc(10* sizeof(char*));
  char a = 'a';
  char *c = &a;

  for ( int i =0; i < 10; i++){
    rec[i] = malloc(10*sizeof(char));
    strcpy(rec[i], c);
    arr[i] = malloc(10*sizeof(char));
    strcpy(arr[i], c);
  }

  rec = realloc(rec, 20* sizeof(char*));
  for (int i =0; i< 20; i++) 
    rec[i] = realloc(rec, 10*sizeof(char));

  arr = realloc(arr, 20* sizeof(char*));
  for (int i = 0; i < 20; i++) 
    arr[i] = realloc(arr, 10*sizeof(char));

  for ( int i =0;i< 10; i++ ) {
    free(rec[i]);
    free(arr[i]);
  }
  free(rec);free(arr);
}

这给了这个坏男孩

*** glibc detected *** ./HW1: realloc(): invalid next size: 0x00000000023d0350 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x75be6)[0x7f1150953be6]
/lib/x86_64-linux-gnu/libc.so.6(+0x7b8bc)[0x7f11509598bc]
/lib/x86_64-linux-gnu/libc.so.6(realloc+0xf0)[0x7f1150959bd0]
./HW1[0x40070b]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd)[0x7f11508fcead]
./HW1[0x400509]
======= Memory map: ========
00400000-00401000 r-xp 00000000 00:2c 8904345153                         /import/linux/home/jkim332/cs220/HW1/HW1
00600000-00601000 rw-p 00000000 00:2c 8904345153                         /import/linux/home/jkim332/cs220/HW1/HW1
023d0000-023f1000 rw-p 00000000 00:00 0                                  [heap]
7f114c000000-7f114c021000 rw-p 00000000 00:00 0
7f114c021000-7f1150000000 ---p 00000000 00:00 0
7f11506c8000-7f11506dd000 r-xp 00000000 00:10 4345426042                 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f11506dd000-7f11508dd000 ---p 00015000 00:10 4345426042                 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f11508dd000-7f11508de000 rw-p 00015000 00:10 4345426042                 /lib/x86_64-linux-gnu/libgcc_s.so.1
7f11508de000-7f1150a5f000 r-xp 00000000 00:10 4343317221                 /lib/x86_64-linux-gnu/libc-2.13.so
7f1150a5f000-7f1150c5f000 ---p 00181000 00:10 4343317221                 /lib/x86_64-linux-gnu/libc-2.13.so
7f1150c5f000-7f1150c63000 r--p 00181000 00:10 4343317221                 /lib/x86_64-linux-gnu/libc-2.13.so
7f1150c63000-7f1150c64000 rw-p 00185000 00:10 4343317221                 /lib/x86_64-linux-gnu/libc-2.13.so
7f1150c64000-7f1150c69000 rw-p 00000000 00:00 0
7f1150c69000-7f1150c89000 r-xp 00000000 00:10 4345380830                 /lib/x86_64-linux-gnu/ld-2.13.so
7f1150e55000-7f1150e58000 rw-p 00000000 00:00 0
7f1150e86000-7f1150e88000 rw-p 00000000 00:00 0
7f1150e88000-7f1150e89000 r--p 0001f000 00:10 4345380830                 /lib/x86_64-linux-gnu/ld-2.13.so
7f1150e89000-7f1150e8a000 rw-p 00020000 00:10 4345380830                 /lib/x86_64-linux-gnu/ld-2.13.so
7f1150e8a000-7f1150e8b000 rw-p 00000000 00:00 0
7fff359d6000-7fff359f7000 rw-p 00000000 00:00 0                          [stack]
7fff359f8000-7fff359fa000 r-xp 00000000 00:00 0                          [vdso]
7fff359fa000-7fff359fc000 r--p 00000000 00:00 0                          [vvar]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

【问题讨论】:

    标签: c arrays memory dynamic segmentation-fault


    【解决方案1】:

    strcpy 要求源字符串(右边的那个)是指向以 NUL 结尾的字符数组的指针。

    但是 'a' 是单个字符,而不是 NUL 终止的字符数组。

    如果只是移动单个字符,请使用 'arr[i] = *c;'或者,为了清楚起见, 'arr[i] = a;'

    但是,这会破坏指向已分配内存的指针。

    如果您尝试用 'a' 填充分配的内存,请使用

    memset(arr[i], 'a', 10);

    如果您只想设置 *arr[i] 数组中的第一个字符,请使用

    *arr[i] = a;或 *arr[i] = 'a';

    (注意,用无意义的名称命名变量,例如发布的代码,会使代码更难阅读。)

    这段代码:

    rec = realloc(rec, 20* sizeof(char*));
    for (int i =0; i< 20; i++) 
        rec[i] = realloc(rec, 10*sizeof(char));
    

    将适用于原来的 10 行,但新行将 包含垃圾指针。

    所以新行将需要一个 malloc 来将这些指针 10...19 设置为指向分配的内存。

    事实上,前 10 行将重新分配就好了,但最后 10 行不是(尚未)有效的指针,因此在最后 10 行上调用 realloc 是未定义的行为,至少会破坏堆和 可能会导致段错误事件。

    【讨论】:

    • 仔细注意循环中传递给realloc的指针参数。
    • 啊,非常感谢你,我没有意识到这一点感到很愚蠢。
    • 根据 IEEE “如果 ptr 是空指针,realloc() 应等效于指定大小的 malloc()。”
    猜你喜欢
    • 1970-01-01
    • 2020-08-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-11
    • 2014-11-07
    • 1970-01-01
    • 1970-01-01
    • 2013-09-04
    相关资源
    最近更新 更多