尝试深度复制结构时出现分段错误
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(©[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);
我有这段代码,其中有一个选区数组,我希望将整个数组深度复制到一个新数组中。现在我也是,看来我做对了,但我一直收到这段代码的分段错误。有人能发现我做错了什么吗?
据我所知,出错的地方在于,在释放旧数组中的堆内存时,这会以某种方式释放存储在新数组中的新堆内存。但是我真的不知道这是怎么回事?
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(©[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);