0

Я пытаюсь читать из stdin в динамический массив строк, используя пробелы в качестве разделителей. Код выглядит следующим образомОшибка при сборе при попытке прочитать stdin для 2d динамически распределенного массива

#include<stdio.h> 
#include<stdlib.h> 
char** parseInput(size_t *numElements) 
{ 
    char **lines; 
    int outerIndex = 0; 
    int innerIndex = 0; 
    int widths = 1; 
    char c=getchar(); 
    lines =(char**) malloc((outerIndex+1)*sizeof(char*)); 
    lines[0] = (char*) malloc(sizeof(char)); 
    while(c!=EOF) 
    { 
    if(innerIndex==widths)//reallocate each strings length, double it 
    { 
     widths+=widths; 
     int i; 
     for(i=0;i<outerIndex+1;i++) 
     lines[i]=(char*)realloc(lines[i],(widths+1)*sizeof(char)); 
    } 
    lines[outerIndex][innerIndex]=c; 
    innerIndex++; 
    if(c==' ')//allocate memory for the next string in the array of strings 
    { 
     lines[outerIndex][innerIndex]='\0'; 
     innerIndex=0; 
     outerIndex++; 
     lines =(char**) realloc(lines,(outerIndex+1)*sizeof(char*)); 
     lines[outerIndex] = (char*) realloc(lines[outerIndex],(widths+1)*sizeof(char)); 
     //the above line in the debugger causes a segfault when outerIndex=19 
    } 
    c=getchar(); 
    } 
    if(innerIndex!=0)//if the last character is not a space, append a space 
    { 
    if(innerIndex==widths) 
    { 
     widths+=widths; 
     int i; 
     for(i=0;i<outerIndex+1;i++) 
     lines[i]=(char*)realloc(lines[i],(widths+1)*sizeof(char)); 
    } 
    lines[outerIndex][innerIndex]=' '; 
    lines[outerIndex][innerIndex+1]='\0'; 
    } 
    *numElements=(size_t)(outerIndex+1); 
    return lines; 
} 
int main() 
{ 
    size_t num =0; 
    char** lines = parseInput(&num); 
} 

Когда внешний размер массива растет ни к чему более 20 переменных, я получаю ошибку сегментации на указанной линии. Например, следующий вход вызывает выдаёт ошибку сегментации

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 

но следующий не

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 

Ошибка отладки говорит

Program received signal SIGSEGV, Segmentation fault. 
0x0000003417e7bf4d in realloc() from /lib64/libc.so.6 

Что это могло быть вызвано? Любая помощь будет оценена по достоинству.

+0

Прошу прощения за более раннее, я вставил, скомпилировал и побежал, это код как есть, и ошибка все еще происходит. – cheesyfluff

+0

Вы бы хорошо научились использовать GDB. Вот достойная ссылка http://www.delorie.com/gnu/docs/gdb/gdb_toc.html – Chimera

ответ

1

На этой линии:

lines[outerIndex] = (char*) realloc(lines[outerIndex], (widths+1)*sizeof(char)); 

вы поставляете неинициализированный указатель в качестве первого аргумента realloc. Вероятно, вы должны использовать здесь malloc.

Другие вопросы:

  • char c должен быть int c (прочитайте документацию для getchar, чтобы понять, почему).
  • Если ввод начинается с пробела, то lines[outerIndex][innerIndex]='\0' пишет за пределы.
  • Код кода, начинающийся if(innerIndex==widths), повторяется дважды в коде; было бы лучше либо сделать это функцией, либо перестроить ваш код, чтобы не повторять это повторение.
  • Вы можете упростить свои вызовы malloc/realloc, удалив избыточные приведения и избыточное умножение на sizeof(char), которое всегда 1.
  • Вы должны проверить malloc/realloc на предмет сбоя и действовать соответствующим образом.
+0

также, не вызывайте realloc, как это. когда он терпит неудачу, вы потеряли исходный указатель на память. Сохраните результат realloc во временную переменную и назначьте ее с успехом. – bruceg

+0

Спасибо, инициализирующая строка [outerIndex] = NULL; перед оператором realloc, похоже, исправили ошибку. – cheesyfluff