我正在编写一个程序来发现从一个顶点到另一个顶点的最佳路径。嗯,我创建了顶点,为邻居列表分配内存。当我创建两个顶点之间的连接时,我重新分配了列表的内存,以便向邻居列表中添加多一个顶点。它似乎在前两次工作,但在第三次崩溃,并给我信号"SIGABRT".I无法在任何论坛找到问题的解决方案。这是我的代码:
typedef struct vertex{
char* name;
Vertex** neighbors;
float x, y;
}Vertex;
Vertex* create_vertex(char* name, float x, float y){
Vertex* vertex = (Vertex*) malloc(sizeof(Vertex));
vertex->x = x;
vertex->y = y;
vertex->name = (char*) malloc(sizeof(char)*strlen(name) + 1);
strcpy(vertex->name, name);
vertex->neighbors = (Vertex**) malloc(sizeof(Vertex*));
vertex->neighbors[0] = NULL;
return vertex;
}
void creates_connection(Vertex* v1, Vertex* v2){
if(areNeighbors(v1, v2)){
printf("Vertices ja sao vizinhos");
return;
}
Vertex** real;
if(v1->neighbors[0] == NULL){
real = (Vertex**) realloc(v1->neighbors, sizeof(Vertex*)+1);
if(real != NULL){
v1->neighbors = real;
v1->neighbors[0] = v2;
v1->neighbors[1] = NULL;
}else printf("Nao foi possivel realocar memoria");
}else{
Vertex* aux = v1->neighbors[0];
int i = 0;
while(aux != NULL){
aux = v1->neighbors[i];
i++;
}
real= (Vertex**) realloc(v1->neighbors, (sizeof(Vertex*))*(i+1));
if(real!= NULL){
v1->neighbors= real;
v1->neighbors[i] = v2;
v1->neighbors[i+1] = NULL;
}else printf("Nao foi possivel realocar memoria");
}
if(v2->neighbors[0] == NULL){
real = (Vertex**) realloc(v2->neighbors, sizeof(Vertex*));
if(real != NULL){
v2->neighbors = realocado;
v2->neighbors[0] = v1;
v2->neighbors[1] = NULL;
}
}else{
Vertex* aux = v2->neighbors[0];
int i = 0;
while(aux != NULL){
aux = v2->neighbors[i];
i++;
}
//HERE, BELLOW, IT CRASHES, DOESN'T PASS TO THE IF
real = (Vertex**) realloc(v2->neighbors, (sizeof(Vertex*))*(i+1));
if(real != NULL){
v2->neighbors = real;
v2->neighbors[i] = v1;
v2->neighbors[i+1] = NULL;
}else printf("Nao foi possivel realcoar memoria");
}
}我不知道这是不是做我正在尝试做的事情的最好方法,我接受建议,但我也想知道发生了什么,我的意思是,为什么会发生这种SIGABRT。
发布于 2018-01-13 23:20:39
这个答案集中于指出发布的代码中的(一些)问题。最后,这个答案包含了对代码更改的建议,该代码更改将与您当前的设计一起工作。如果你愿意重新设计,看看@wildplasser的答案
这里有个问题
if(v1->neighbors[0] == NULL){
real = (Vertex**) realloc(v1->neighbors, sizeof(Vertex*)+1);
^^^^
This only increase with 1 byte
but you want 1 pointer还有这里
if(v2->neighbors[0] == NULL){
real = (Vertex**) realloc(v2->neighbors, sizeof(Vertex*));
^^^^
No increase at all此外,这里还存在一个问题:
Vertex* aux = v1->neighbors[0];
int i = 0;
while(aux != NULL){
aux = v1->neighbors[i];
i++;
}
real= (Vertex**) realloc(v1->neighbors, (sizeof(Vertex*))*(i+1));由于您的设计要求数组的末尾始终有一个空指针,因此您需要让i从1开始,即
int i = 1;此外,当您写出端分配的内存时,这部分也有一个问题-记住索引从零开始:
real= (Vertex**) realloc(v1->neighbors, (sizeof(Vertex*))*(i+1));
if(real!= NULL){
v1->neighbors= real;
v1->neighbors[i] = v2;
v1->neighbors[i+1] = NULL; // UPS... write outside allocated memory
// Writing to [i+1] requires that you
// have i+2 pointers but you only
// have i+1有趣的是,当第一个指针为NULL时,您不需要处理这两种特殊情况。else中的代码还可以处理第一个指针为空的情况。
所以这段代码:
if(v1->neighbors[0] == NULL){
real = (Vertex**) realloc(v1->neighbors, sizeof(Vertex*)+1);
if(real != NULL){
v1->neighbors = real;
v1->neighbors[0] = v2;
v1->neighbors[1] = NULL;
}else printf("Nao foi possivel realocar memoria");
}else{
Vertex* aux = v1->neighbors[0];
int i = 0;
while(aux != NULL){
aux = v1->neighbors[i];
i++;
}
real= (Vertex**) realloc(v1->neighbors, (sizeof(Vertex*))*(i+1));
if(real!= NULL){
v1->neighbors= real;
v1->neighbors[i] = v2;
v1->neighbors[i+1] = NULL;
}else printf("Nao foi possivel realocar memoria");
}可以简化为
Vertex* aux = v1->neighbors[0];
int i = 1; // NOTICE: Use 1 instead of 0
while(aux != NULL){
aux = v1->neighbors[i];
i++;
}
real= (Vertex**) realloc(v1->neighbors, (sizeof(Vertex*))*(i+1));
if(real!= NULL){
v1->neighbors= real;
v1->neighbors[i-1] = v2; // NOTICE: i-1
v1->neighbors[i] = NULL; // NOTICE: i
}else printf("Nao foi possivel realocar memoria");这也适用于处理v2的第二个块
发布于 2018-01-13 23:25:29
重新分配而不是指针数组末尾的空标记,你可以跟踪每次加法时的(used)size
()就像重新分配你的()分配一样,它会集中你的错误
#include <stdlib.h>
struct vertex{
char* name;
float x, y;
unsigned size, used;
struct vertex **neighbors;
};
struct vertex *create_vertex(char* name, float x, float y){
struct vertex *vv = malloc(sizeof *vv );
vv->x = x;
vv->y = y;
vv->name = strdup(name);
vv->size=0;
vv->used=0;
vv->neighbors = NULL;
return vv;
}
static void resize_vertex(struct vertex *pp, unsigned newsize)
{
struct vertex **tmp;
if (!newsize)newsize =4;
tmp = realloc(pp->neighbors, newsize * sizeof *pp->neighbors );
if(!tmp) { /* handlefailure */ }
pp->neighbors = tmp;
pp->size = newsize;
}
void creates_connection(struct vertex* v1, struct vertex* v2){
if(areNeighbors(v1, v2)){
printf("Vertices ja sao vizinhos");
return;
}
if(v1->used== v1->size) resize_vertex(v1, 2*v1->size);
v1->neighbors[v1->used] = v2;
v1->used += 1;
return;
}https://stackoverflow.com/questions/48240958
复制相似问题