尝试深度复制结构时出现分段错误

Segementation fault whilst trying to deep copy struct

我有这段代码,其中有一个选区数组,我希望将整个数组深度复制到一个新数组中。现在我也是,看来我做对了,但我一直收到这段代码的分段错误。有人能发现我做错了什么吗?

据我所知,出错的地方在于,在释放旧数组中的堆内存时,这会以某种方式释放存储在新数组中的新堆内存。但是我真的不知道这是怎么回事?

main.c

int main() {
    const int numConstituencies = 5;
    struct Constituency constituencies[numConstituencies];

    constructConstituency(
        &constituencies[0], "London",
        (unsigned int[]){1, 2, 3, 4}, 4);
    constructConstituency(
        &constituencies[1], "Manchester",
        (unsigned int[]){0, 2}, 2);
    constructConstituency(
        &constituencies[2], "Leeds",
        (unsigned int[]){0, 1, 3}, 3);
    constructConstituency(
        &constituencies[3], "Liverpool",
        (unsigned int[]){0, 2, 4}, 3);
    constructConstituency(
        &constituencies[4], "Newcastle",
        (unsigned int[]){0, 3}, 2);

    struct Constituency * copy = copyConstituencies(constituencies,
                                                    numConstituencies);

    int i;
    for (i = 0; i < numConstituencies; i++) {
        destructConstituency(&constituencies[i]);
    }

    for (i = 0; i < numConstituencies; i++) {
        destructConstituency(&copy[i]);
    }
    return 0;

constituency.c

struct Constituency {
    char *name;
    unsigned int *neighbours;
    unsigned int numNeighbours;
};

void clearValues(struct Constituency * const constituency) {
    constituency->name = NULL;
    constituency->neighbours = NULL;
    constituency->numNeighbours = 0;
}

void constructConstituency(struct Constituency * const constituency,
                           char * const name,
                           unsigned int * const neighbours,
                           unsigned int numNeighbours) {

    clearValues(constituency);

    int nameLength = strlen(name) + 1; // [=11=] terminated string

    constituency->numNeighbours = numNeighbours;
    constituency->name = (char *) malloc(sizeof(char) * nameLength);
    constituency->neighbours = (unsigned int *) malloc(sizeof(unsigned int) * numNeighbours);
   if (constituency->name == NULL || constituency->neighbours == NULL) {
       printf("Unable to allocate for constituency: %s\n", name);
       exit(1);
   }

    memcpy(constituency->name, name, sizeof(char) * nameLength);
    memcpy(constituency->neighbours, neighbours, sizeof(unsigned int) * numNeighbours);
}

struct Constituency * copyConstituencies(struct Constituency * const constituencies,
                                         unsigned int const numConstituencies) {

    struct Constituency newConstituencies[numConstituencies];

    int i;
    for (i = 0; i < numConstituencies; i++) {
        constructConstituency(&newConstituencies[i],
                              constituencies[i].name,
                              constituencies[i].neighbours,
                              constituencies[i].numNeighbours);
    }

    return newConstituencies;
}

void destructConstituency(struct Constituency * const constituency) {
    free(constituency->name);
    free(constituency->neighbours);

    clearValues(constituency);
}

在这个函数中

struct Constituency * copyConstituencies(struct Constituency * const constituencies,
                                         unsigned int const numConstituencies) {

    struct Constituency newConstituencies[numConstituencies];

    int i;
    for (i = 0; i < numConstituencies; i++) {
        constructConstituency(&newConstituencies[i],
                              constituencies[i].name,
                              constituencies[i].neighbours,
                              constituencies[i].numNeighbours);
    }

    return newConstituencies;
}

您正在返回一个指向本地数组的指针,该数组在退出该函数后将不再存在。因此返回的指针无效并且取消引用指针会调用未定义的行为。

您需要动态分配数组:


    struct Constituency *newConstituencies = malloc(sizeof(struct Constituency) * numConstituencies);