Ошибка сегментации при доступе и изменении массива строк (char *) в C - PullRequest
0 голосов
/ 24 октября 2018

Я получаю ошибки сегментации (с выводом gdb «??» на трассировках) в программе, которую я пытаюсь скомпилировать некоторое время сейчас и после многих попыток (таких, как перепрограммирование структуры данных, которую я использовал, котораядолжен работать сейчас) Я все еще продолжал получать segfaults, хотя теперь он дал мне строку (к которой я добавил комментарий).

getMains () запускается несколько раз для токенизации разных строк из одного файла.

Я хотел, чтобы mains был массивом размера 4, но при передаче его как "char * mains [4]" я получил ошибку компиляции за попытку передать ему массив (*) [4], которого у меня никогда не былоразобрался заранее (только начал использовать C).Я предполагаю, что это может быть проблемой, если я пытаюсь получить доступ к какой-либо части, которая не использовалась, но проблема возникает при инициализации индексов массива.

Код, который я пытаюсь заставить работать, где аргумент "char *** mains" принимает & (char **) из отдельной функции "runner", которую я хочу отредактироватьтак что я могу посмотреть его содержимое в "runner":

bool getMains(FILE * file, char *** mains)
{
    char line[256];
    int start = 0;
    char * token;
    const char * mainDelim = "\t \n\0", * commDelim = "\n\t\0";

    if(fgets(line, sizeof(line), file) == NULL)
        return false;

    while(line[0] == '.')
        if(fgets(line, sizeof(line), file) == NULL);
            return false;

    if(line[0] == '\t' || line[0] == ' ')
    {
        (*mains)[0] = " ";
        start = 1;
    }

    token = strtok(line, mainDelim);
    int i;
    for(i = start; token != NULL; ++i)
    {
        (*mains)[i] = strdup(token); // <- gdb: Segmentation Fault occurs here

        if(i % 3 == 2)
            token = strtok(NULL, commDelim);
        else
            token = strtok(NULL, mainDelim);
     }

     free(token); // Unsure if this was necessary but added in case.
     return true;
}


/* Snippet of code running it... */
void runner(FILE * file) {
    char ** mains;
    if(!getMains(*file, &mains))
        return;
    while(strcmp(mains[1], "END") != 0){
        /* do stuff lookinig through indices 0, 1, 2, & 3 */
        if(!getMains(*file, &mains))
            break;
    }
}

Есть ли какие-либо советы по этому поводу или просто вообще безопасно изменить массивы с помощью других функций?

Должен ли я заменить getMains () на "getMains(FILE * file, char ** mains [4]); "и передать ему & "char * mains [4]") для того, чтобы он был установлен в желаемом размере?Или это также приведет к ошибкам?

1 Ответ

0 голосов
/ 24 октября 2018

Вам нужно выделить память для сети, она должна выглядеть следующим образом:

char ** mains;
mains = malloc(some number N * sizeof(char*));

Вам нужно что-то вроде этого, если вы не используете strdup, который выделяет память для вас:

for (int i = 0; i < N; ++i) {
  mains[i] = malloc(some number K);
}

Во всех случаях не забывайте звонить free на каждый указатель, полученный вами от malloc или strdup.Вы можете пропустить эту часть, если программа заканчивается сразу после того, как вы позвоните free.

...