Ошибка сегментации отчета, когда цикл - PullRequest
0 голосов
/ 05 июля 2018
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct group {
    int no;
    int people_len;
    struct people *peoples;
    int weight;
};

struct people {
    char name[4];
    int weight;
};

int main() {
    int n,k;
    if (scanf("%d %d", &n, &k) < 2) return 0;

    struct group *g;
    char from[4], to[4];
    int f1 = -1, f2 = -1, time, g_len = 0, p_len = 0;
    for (int i=0;i<n;i++) {
        if (scanf("%s %s %d", from, to, &time) < 3) return 0;
        g = realloc(g, (g_len+1) * sizeof(struct group));
        g[g_len].no = g_len;
        g[g_len].people_len = 2;
        g[g_len].peoples = malloc(2 * sizeof(struct people));
        strcpy(g[g_len].peoples[0].name, from);
        strcpy(g[g_len].peoples[1].name, to);
        g[g_len].weight = time;
        g_len++;
    }
}

Когда я получаю параметры, он сообщает об ошибке «Ошибка сегментации», я знаю, что память не обрабатывается должным образом, но я не могу найти проблему.

Ввод:

8 59
AAA BBB 10
BBB AAA 20
AAA CCC 40
DDD EEE 5
EEE DDD 70
FFF GGG 30
GGG HHH 20
HHH FFF 10

Ответы [ 2 ]

0 голосов
/ 05 июля 2018

Вам нужно:

struct group *g = NULL;

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

Также обратите внимание, что если всегда будет 2 человека, лучше просто сделать:

struct people peoples[2];

внутри структуры, чтобы сократить выделение кучи и упростить задачу.

Также принято / стандартно не делать перераспределение по одному элементу за раз, а вместо этого позволить ему расти экспоненциально, удваивая размер при каждой новой потребности в выделении или, наконец, добавляя большее количество элементов. Это связано с тем, что выделение динамической памяти является дорогостоящим (на это требуется время), поэтому для производительности полезно сделать меньше распределений, если это возможно. Конечно, это требует отслеживания фактического используемого / действительного массива отдельно от выделенной длины.

0 голосов
/ 05 июля 2018

Проблема выглядит как в

g = realloc(g, (g_len+1) * sizeof(struct group));

где аргумент g неинициализирован и указывает на недопустимую ячейку памяти.

Цитата C11, глава §7.22.3.5

Если ptr является нулевым указателем, функция realloc ведет себя как функция malloc для указано size. В противном случае, если ptr не совпадает с указателем, ранее возвращенным памятью функция управления, или если пространство было освобождено путем вызова free или realloc функция, поведение не определено. [...]

Так как в вашем случае g является автоматической локальной переменной, она унифицируется и содержит неопределенное значение. Чтобы сделать это правильно, вам нужно инициализировать его как NULL, что-то вроде

struct group *g = NULL;
...