Странная ошибка сегментации C - PullRequest
0 голосов
/ 23 февраля 2019

Итак, у меня есть этот бит кода

int main(int argc, char *argv[]) {
    char *vendas[1];
    int size = 1;
    int current = 0;
    char buffer[50];
    char *token;
    FILE *fp = fopen("Vendas_1M.txt", "r");

    while(fgets(buffer, 50, fp)) {
        token = strtok(buffer, "\n");
        if (size == current) {
            *vendas = realloc(*vendas, sizeof(vendas[0]) * size * 2);
            size *= 2;
        }
        vendas[current] = strdup(token);
        printf("%d - %d - %s\n", current, size, vendas[current]);
        current++;
    }
}

Вот в чем дело ... Используя GDB, он дает ошибку сегментации на

vendas[current] = strdup(token);

, но самая странная вещь - это работаетпока размер его на 1024.Размер увеличивается до 1024, а затем он просто выдает ошибку сегментации около 1200 элементов.Я знаю, что проблема заключается в перераспределении памяти, потому что она работала, когда у меня был статический массив.Просто не могу понять, что.

Ответы [ 2 ]

0 голосов
/ 23 февраля 2019

Вы не можете перераспределить локальный массив, вы хотите, чтобы vendas был указателем на выделенный массив указателей: char **vendas = NULL;.

Вы также должны включить правильные заголовочные файлы и проверить на fopen()и realloc() ошибка.

Вот модифицированная версия:

#include <stdio.h>
#include <stdlib.h>

void free_array(char **array, size_t count) {
    while (count > 0) {
        free(array[--count]);
    }
    free(array);
}

int main(int argc, char *argv[]) {
    char buffer[50];
    char **vendas = NULL;
    size_t size = 0;
    size_t current = 0;
    char *token;
    FILE *fp;

    fp = fopen("Vendas_1M.txt", "r");
    if (fp == NULL) {
        printf("cannot open file Vendas_1M.txt\n");
        return 1;
    }
    while (fgets(buffer, sizeof buffer, fp)) {
        token = strtok(buffer, "\n");
        if (current >= size) {
            char **savep = vendas;
            size = (size == 0) ? 4 : size * 2;
            vendas = realloc(vendas, sizeof(*vendas) * size);
            if (vendas == NULL) {
                printf("allocation failure\n");
                free_array(savep, current);
                return 1;
            }
        }
        vendas[current] = strdup(token);
        if (vendas[current] == NULL) {
            printf("allocation failure\n");
            free_array(vendas, current);
            return 1;
        }
        printf("%d - %d - %s\n", current, size, vendas[current]);
        current++;
    }
    /* ... */
    /* free allocated memory (for cleanliness) */
    free_array(vendas, current);
    return 0;
}    
0 голосов
/ 23 февраля 2019

В вашем массиве char *vendas[1] есть место только для одного (1) указателя.Так что во второй раз вы находитесь за пределами массива и находитесь в неопределенной области поведения.

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

...