двойной указатель ошибки сегментации

У меня ошибка сегментации в следующем коде, и я действительно не вижу, что я пропустил, цель этого кода — извлечь строки .csv и поместить их в двумерный массив, созданный с помощью двойного указателя.

Ошибка seg находится в последнем назначении открытых текстов [i][j] для 1-й строки файла csv.

Ваша помощь будет высоко оценена (по этой проблеме со вчерашнего дня...)

int main(){


int n=48; //nbers of columns in csv file
int m=60; //nbers of lines in csv file


int cpt,i,j;
cpt=0;
i=0;
FILE *fp;
char *token;
const char s[2] = ",";

unsigned char **plaintexts;
plaintexts = malloc(sizeof(*plaintexts) * m);

char *str=malloc(sizeof(char)*15*n); //maximum 15 char per box
fp = fopen("aes_traces.csv","r");




while(fgets(str,15*n,fp)!=NULL){

    plaintexts[i] = malloc(sizeof(*plaintexts[i]) * n);
    token = strtok(str,s);
    j=0;
    while(token != NULL){
        printf("%s\n", token);
        token = strtok(NULL,s);
        plaintexts[i][j]=(unsigned char) (*token);

        j++;

    }

    i++;
    free(str);
    free(token);
}


fclose(fp);

}

person Addon    schedule 29.12.2015    source источник
comment
Каковы значения i, j, n и token при возникновении ошибки?   -  person David Schwartz    schedule 29.12.2015
comment
Можете ли вы запустить valgrind для своей программы и опубликовать результаты здесь?   -  person loginn    schedule 29.12.2015
comment
Если вам нужен массив строк, когда каждая строка представляет собой массив токенов, вам нужен трехмерный массив, поскольку каждый токен представляет собой массив символов.   -  person n. 1.8e9-where's-my-share m.    schedule 29.12.2015
comment
Более того, ваша структура внутреннего цикла неверна. Когда вы говорите while (token != NULL), вы можете использовать *token перед назначением token в теле цикла, но не после. Вы также теряете самый первый токен. Подумайте, как решить обе проблемы сразу одним простым изменением.   -  person n. 1.8e9-where's-my-share m.    schedule 29.12.2015


Ответы (1)


while(token != NULL){
    printf("%s\n", token);
    token = strtok(NULL,s); // A
    plaintexts[i][j]=(unsigned char) (*token); // B

    j++;
}

Если этот цикл запустится хотя бы один раз, он завершится segfault. Почему? Цикл не может завершиться до тех пор, пока token не будет установлен в NULL в строке, которую я пометил A, а затем не будет разыменован в строке, которую я пометил B. Разыменование NULL приведет к segfault.

person David Schwartz    schedule 29.12.2015
comment
Спасибо, Дэвид, это решает эту проблему сегментации (я перевернул строки A и B), но теперь у меня есть еще одна для i = 1, когда я выполняю malloc для открытых текстов [i]... - person Addon; 29.12.2015
comment
Вам нужно научиться устранять неполадки. Узнайте, как точно определить, какая строка кода вызывает segfault и что эта строка кода делает неправильно, что приводит к segfault. - person David Schwartz; 29.12.2015
comment
Я согласен с вами, Дэвид, просто эта проблема должна быть частью гораздо более крупного проекта, который я должен сделать для школы, и я пытаюсь решить ее как можно быстрее, я думаю, что не понимаю, как двойные указатели и 2d массивы работают, я должен проверить это - person Addon; 29.12.2015
comment
Попробуйте объяснить, что там делают free(token) и free(str). Сколько раз вы их освобождаете? Сколько раз вы их malloc? - person n. 1.8e9-where's-my-share m.; 29.12.2015
comment
Спасибо ! Когда я удалил «free (str)», больше нет ошибки Seg! Я не понимаю, почему... это просто освобождает область, на которую указывает str, и я не вижу связи с malloc открытых текстов[i] - person Addon; 29.12.2015
comment
Используйте valgrind для устранения неполадок. Проблема может быть до вызова free. - person David Schwartz; 29.12.2015
comment
У вас нет segfault, но вы не знаете, правильно ли вы построили массив. - person n. 1.8e9-where's-my-share m.; 29.12.2015