2015-04-17 4 views
0

Итак, я пытаюсь перераспределить массив 2d char, и он продолжает сбой У меня есть stdlib.h, и я по-прежнему пробовал его с приведениями на всякий случай и получил ту же ошибку. Я думаю, что ошибка возникает, когда я пишу (используйте strcpy)2d динамический массив строк realloc вызывает ошибку

Это на самом деле только боковая тестовая программа, потому что я не могу получить другую программу, которая имеет дело с растущими 2d-массивами. Я получаю ошибку сегментации, когда я 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] 

ответ

2

зЬгсру требует строки источника (один справа), чтобы быть указателем на завершенном нуль массива символов.

Однако 'a' - это один символ, а не NUL-завершенный массив символов.

Для простого перемещения этого одиночного символа используйте 'arr [i] = * c;' ИЛИ, для ясности, 'arr [i] = a;'

Однако это может привести к разложению указателей на выделенную память.

Если вы пытаетесь заполнить выделенную память с 'а' затем использовать

MemSet (обр [я], 'а', 10);

Если ваш единственный пытается установить первый characterin в * обр [я] массив, а затем использовать

* обр [я] = а; или * 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 строк будут realloc просто отлично, но последние 10 строк не являются (пока) действительными указателями, поэтому вызов realloc в этих последних 10 строках - это неопределенное поведение, которое, по крайней мере, испортит куча и , вероятно, приводят к событию сбоя seg.

+1

Обратите внимание, что аргумент указателя передан 'realloc' в циклы. – WhozCraig

+0

Ах, спасибо, я так глуп, что не понимаю этого. – user3400223

+0

Согласно IEEE «Если ptr является нулевым указателем, realloc() должен быть эквивалентен malloc() для указанного размера». – user3400223