2015-08-30 2 views
1

У меня есть массив строк (char **), и мне нужно сделать некоторое перераспределение, когда оно достигнет своей емкости. Таким образом, в этой функции я создаю новый массив, выделяя размер два раза больше, чем раньше, и для каждой строки в старом массиве я выделяю пространство для нового массива и копирую содержимое. Код выглядит следующим образом:C Матрица перераспределения, ведущая к segfault

void matrix_double (char ***arrayptr, int *size) { 
    char **array = *arrayptr, **newarr; 
    int i, wordsize; 
    newarr = malloc (*size * 2); 
    for (i = 0; i < *size; i++) { 
     wordsize = strlen (array[i]); 
     newarr[i] = malloc (wordsize + 1); 
     strcpy (newarr[i], array[i]); 
     free (array[i]); 
    } 
    *size *= 2; 
    free (array); 
    *arrayptr = newarr; 
} 

Однако, я получаю много ошибки сегментации при выделении пространства для новых строк в 7-й строке. Согласно Valgrind, команды malloc выделяют пространство из пространства, выделенного для массива, которое мало - я использую массивы из 10 или 20 строк максимум - и поэтому он переполняется в другие выделенные области, вызывая segfaults. Если я сталкиваюсь в памяти массив выделения вверх (например, malloc (*size * 200) все проходит гладко.

Любые идеи о том, что происходит? Не видел такое поведение нигде.

+3

'malloc (* size * 2);' - вы, кажется, забыли, что вам следует выделять массивы * указателей * в некоторых местах; а не только символы. – WhozCraig

+0

Когда вы изменяете размер массива, вам не нужно создавать копии строк; вы можете просто назначить указатель в старом массиве соответствующему указателю в новом массиве. Это позволит сэкономить много копий, если ваш массив имеет размер. Вы должны рассмотреть достоинства (и недостатки переносимости) ['strdup()'] (http://pubs.opengroup.org/onlinepubs/9699919799/functions/strdup.html). Вам также необходимо решить, как вы справитесь с сбоем распределения памяти. –

ответ

0

malloc аргумент размер в байтах. Таким образом, вы должны позвонить это как

malloc(sizeof(char *) * (*size) * 2);

позвонив

malloc(*size * 2);

Вы выделяете 2*size байт памяти, которых недостаточно для size указателей.

+0

Вы правы. Я думал, что указатель возьмет только один байт, но вместо этого потребовалось 8. Благодаря! –

+1

@ Указатели GustavoSilva принимают 32-битную 32-битную систему и 64-разрядную в 64-битной системе. Так что не жёсткий код – EvgeniyZh

Смежные вопросы