我想对图形进行编程,但是在添加顶点时遇到问题。当我想重新分配内存时,程序停止,控制台仅显示“ aborted(核心转储)”。
这是我的代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
struct Graph
{
int VertexCounter;
struct Vertices *vertex;
struct Edge **adjMat;
}MyGraph;
struct Vertices
{
int id;
char name[15];
float xPos;
float yPos;
};
struct Edge
{
int id;
struct Vertices *start;
struct Vertices *end;
};
//Initializing a graph with memory for one Vertex and one 1x1 adjecency Matrix but setting the number of Vertices to zero
void initGraph(struct Graph *graph)
{
graph = (struct Graph *) calloc(1, sizeof(struct Graph));
graph->vertex = (struct Vertices *) calloc(1, sizeof(struct Vertices));
graph->adjMat = (struct Edge **) calloc(1, sizeof(struct Edge *));
*(graph->adjMat) = (struct Edge *) calloc(1, sizeof(struct Edge));
graph->VertexCounter = 0;
printf("Number of Vertices: %d\n", graph->VertexCounter);
}
//printing the number of Vertices
void test(struct Graph *graph)
{
printf("Number of Vertices: %d\n", (*graph).VertexCounter);
}
//Reallocating the memory for an additional Vertex.
//I multiply the VertexCounter - 1 because the struct Graph contains space for one pointer of the type (struct Vertices *)
void addVertex(struct Graph *graph)
{
graph->VertexCounter++;
graph = (struct Graph *) realloc(graph, sizeof(struct Graph) +
(graph->VertexCounter - 1) * sizeof(struct Vertices));
}
int main()
{
struct Graph *graphPointer;
graphPointer = &MyGraph;
initGraph(graphPointer);
test(graphPointer);
addVertex(graphPointer);
test(graphPointer);
return 0;
}
输出:
顶点数:0
顶点数:0
中止(核心已弃用)
因此,函数addVertex(struct Graph *)不起作用。
我尚未包括新Edge的重新分配。
我该如何解决?
更新:
void addVertex(struct Graph **graph)
{
(*graph)->VertexCounter++;
*graph = realloc(*graph, sizeof(struct Graph) +
((*graph)->VertexCounter - 1) * sizeof(struct Vertices));
}
int main()
{
struct Graph *graphPointer;
graphPointer = &MyGraph;
initGraph(graphPointer);
test(graphPointer);
addVertex(&graphPointer);
test(graphPointer);
return 0;
}
这将返回与以前相同的输出
更新2:
void initGraph(struct Graph **graph)
{
(*graph) = (struct Graph *) calloc(1, sizeof(struct Graph *));
(*graph)->vertex = (struct Vertices *) calloc(1, sizeof(struct Vertices));
(*graph)->adjMat = (struct Edge **) calloc(1, sizeof(struct Edge *));
*((*graph)->adjMat) = (struct Edge *) calloc(1, sizeof(struct Edge));
(*graph)->VertexCounter = 0;
printf("Number of Vertices: %d\n", (*graph)->VertexCounter);
}
//printing the number of Vertices
void test(struct Graph *graph)
{
printf("Number of Vertices: %d\n", (*graph).VertexCounter);
}
//Reallocating the memory for an additional Vertex.
//I multiply the VertexCounter - 1 because the struct Graph contains space for one pointer of the type (struct Vertices *)
void addVertex(struct Graph **graph)
{
(*graph)->VertexCounter++;
void *temp = realloc(temp, sizeof(struct Graph *));
*graph = temp;
if(graph == NULL)
printf("Realloc failed");
}
int main()
{
struct Graph *graphPointer;
graphPointer = &MyGraph;
initGraph(&graphPointer);
test(graphPointer);
addVertex(&graphPointer);
test(graphPointer);
return 0;
}
我更改了initGraph和addVertex,但输出不会更改。
最佳答案
如以上注释中所指出的,您需要跟踪更改时间,或者可以更改graphPointer。例如,每次调用realloc时,系统可能会被迫移动您的结构,并返回指向新分配的新指针。再次指出,例如,在addVertex的末尾将丢弃此新指针。如果要更改函数中的指针,就像其他任何“按引用调用”参数一样,请将指针传递给它。 (如果您对类型完全严格,只有在确定需要进行类型转换时,编译器才能提供帮助。)
您真正需要做的另一件事是检查呼叫的返回值。有时您认为调用有效,但无效,并且由于参数错误而总是返回NULL。无论哪种方式,您都不希望您的程序在将来某个时候崩溃而没有任何原因的提示。因此,例如,如果重新分配失败,则至少打印该重新分配失败并退出。