C语言 如何从结构数组中复制结构?



我意识到所有printf都变得有点长,但我真的不知道如何更好地呈现我的问题。

我在正确初始化 c 中的结构时遇到问题。我尝试使用printf进行调试以显示我的问题。本质上,我使用以下函数创建一个结构列表:

Vertex *Vertex_new(int n){
Vertex *vert = malloc(sizeof(Vertex));
if(!vert){return NULL;}
vert->id = n;
vert->outNeighbours = malloc(sizeof(LinkedList));
vert->outNeighbours = LinkedList_new();
vert->inNeighbours = malloc(sizeof(LinkedList));
vert->inNeighbours = LinkedList_new();
return vert;
}
struct Vertex {
int id; // a number in [0; numVertices[
LinkedList *outNeighbours; // A linked list of vertices.
LinkedList *inNeighbours; // A linked list of vertices
};

这用于创建以下结构,紧随其后的函数。之后的函数,称为Graph_new(),我在将Vertex正确保存在列表中时遇到了问题。我不知道我做错了哪一部分,但我假设这与我如何初始化列表有关,因此做了一堆打印语句来尝试理解问题:

struct Graph {
int numVertices;
int numEdges;
Vertex *vertices; // An array of numVertices vertices
};

Graph *Graph_new(int n){
Graph *grf = malloc(sizeof(Graph));
if(!grf){return NULL;}
grf->numEdges = 0;
grf->numVertices = n;
Vertex list[n];
grf->vertices = malloc(sizeof(Vertex*)*n);
for(int i = 0; i < n;i++){
list[i] = *Vertex_new(i);
}
grf->vertices = list;
// My attempt at debugging, `grf` is simply returned after these print statements:
printf("Inside graph_new for list:n");
printf("%d ",list[0].id);
printf("%d ",list[1].id);
printf("%d ",list[2].id);
printf("%d ",list[3].id);
printf("%d n",list[4].id);
// Det her virker herinde, men ikke uden for
// er der et problem i hvordan jeg gemmer listen?
printf("Inside graph_new for grf->vertices:n");
printf("%d ",grf->vertices[0].id);
printf("%d ",grf->vertices[1].id);
printf("%d ",grf->vertices[2].id);
printf("%d ",grf->vertices[3].id);
printf("%d n",grf->vertices[4].id);
printf("%d ",grf->vertices[0].id);
printf("%d ",grf->vertices[1].id);
printf("%d ",grf->vertices[2].id);
printf("%d ",grf->vertices[3].id);
printf("%d n",grf->vertices[4].id);

return grf;
}

在另一个函数中,我调用graph_new(n)n在这里从文件中读取,n在这种情况下是 5,我已经测试过,以确保它正确读取它,所以它是保证的 5。 我测试了两种打印方式,以了解正在发生的事情。第一个:

Graph *newG = Graph_new(n);

// outside of graph_new:
printf("outside of graph_new, newG->vertices:n");
printf("%d ",newG->vertices[0].id);
printf("%d ",newG->vertices[1].id);
printf("%d ",newG->vertices[2].id);
printf("%d ",newG->vertices[3].id);
printf("%d n",newG->vertices[4].id);
printf("%d ",newG->vertices[0].id);
printf("%d ",newG->vertices[1].id);
printf("%d ",newG->vertices[2].id);
printf("%d ",newG->vertices[3].id);
printf("%d n",newG->vertices[4].id);

给出输出:

Inside graph_new for list:
0 1 2 3 4 
Inside graph_new for grf->vertices:
0 1 2 3 4 
0 1 2 3 4 
outside of graph_new, newG->vertices:
0 -285208794 -603392624 -603392624 0 
0 -285208794 -603392624 -603392624 0

所以起初我以为这是因为列表没有正确保存,或者顶点没有正确保存在列表中。

但是如果我然后在Graph_new外面打印这个:

Vertex vert1 = newG->vertices[0];
Vertex vert2 = newG->vertices[1];
Vertex vert3 = newG->vertices[2];
Vertex vert4 = newG->vertices[3];
Vertex vert5 = newG->vertices[4];
printf("works outside:n");
printf("%d ", vert1.id);
printf("%d ", vert2.id);
printf("%d ", vert3.id);
printf("%d ", vert4.id);
printf("%d n", vert5.id);  
// Saving the vertices back in the array works
newG->vertices[0] = vert1;
newG->vertices[1] = vert2;
newG->vertices[2] = vert3;
newG->vertices[3] = vert4;
newG->vertices[4] = vert5;
Vertex vert11 = newG->vertices[0];
Vertex vert22 = newG->vertices[1];
Vertex vert33 = newG->vertices[2];
Vertex vert44 = newG->vertices[3];
Vertex vert55 = newG->vertices[4];  
printf("Works againn");
printf("%d ", vert11.id);
printf("%d ", vert22.id);
printf("%d ", vert33.id);
printf("%d ", vert44.id);
printf("%d n", vert55.id);
// ------------------------------
printf("Doesn't work: n");
Vertex vvert1 = newG->vertices[0];
Vertex vvert2 = newG->vertices[1];
Vertex vvert3 = newG->vertices[2];
Vertex vvert4 = newG->vertices[3];
Vertex vvert5 = newG->vertices[4];
printf("%d ", vvert1.id);
printf("%d ", vvert2.id);
printf("%d ", vvert3.id);
printf("%d ", vvert4.id);
printf("%d n", vvert5.id);

我得到以下输出:

Inside graph_new for list:
0 1 2 3 4 
Inside graph_new for grf->vertices:
0 1 2 3 4 
0 1 2 3 4 
works outside:
0 1 2 3 4 
Works again
0 1 2 3 4 
Doesn't work: 
0 -2035597530 519880720 -2031896736 -1398417392

如果有人有时间理解它并伸出援助之手,我将不胜感激。我可能无法及时参加考试,但至少我知道我做错了什么。

Graph *Graph_new(int n){
…
Vertex list[n];
grf->vertices = malloc(sizeof(Vertex*)*n);
for(int i = 0; i < n;i++){
list[i] = *Vertex_new(i);
}
grf->vertices = list;
…
return grf;
}

list数组是函数Graph_new本地的,一旦控件退出函数,就会被销毁,因此您不能引用listGraph_new它是未定义的行为。

此外,*Vertex_new(i);内存泄漏,因为您正在丢失对分配的引用。

最新更新