具有空指针的图形的奇怪输出
Strange output of a Graph with void pointers
我正在尝试构建一个可以处理具有邻接列表或矩阵的图的程序,为此老师教我们将邻接声明为 void *,以便将其转换为列表或矩阵。
使用下面的代码我得到了这个输出:
如您所见,B 节点中存在一些奇怪的东西。
如果我尝试使用 CodeBlocks 进行调试,调试器会在 appendNodeList
at if (L->target != target) {..
中给出 Segmentation Fault
我认为 initGraphList
中的动态分配有问题,但我不知道如何解决它。
您认为这里的问题是什么?是分配吗?如果是,我该如何解决?
在此先感谢您的帮助!
代码:
main.c
#include <stdio.h>
#include <stdlib.h>
#include "Graph.h"
int main(int argc, const char * argv[]) {
Graph G = NULL;
G = initGraphList(3);
addEdgeList(G, 0, 1, 1);
addEdgeList(G, 0, 2, 2);
addEdgeList(G, 1, 0, 3);
addEdgeList(G, 1, 2, 4);
addEdgeList(G, 2, 0, 5);
addEdgeList(G, 2, 1, 6);
printGraphList(G);
return 0;
}
Graph.h
#include "List.h"
struct TGraph {
void **adj;
int nodes_count;
};
typedef struct TGraph *Graph;
typedef struct AdjList{
List *nodes;
}AdjList;
Graph initGraphList(int);
void printGraphList(Graph G);
void addEdgeList(Graph G, int source, int target, float peso);
Graph.c
#include <stdio.h>
#include <stdlib.h>
#include "Graph.h"
Graph initGraphList(int nodes_count){
Graph G = (Graph)malloc(sizeof(struct TGraph));
G->adj = malloc(sizeof(AdjList));
G->nodes_count = nodes_count;
((AdjList *)(G->adj))->nodes = malloc(nodes_count * sizeof(List));
return G;
}
void printGraphList(Graph G) {
if (G != NULL) {
int i;
for(i = 0; i < G->nodes_count; i++) {
printf("%c -> ", i + 'A'); //I use this in order to print out the nodes as A,B,C,.. instead of 0,1,2,...
printList(((AdjList *)(G->adj))->nodes[i]);
puts("\n");
}
}
}
void addEdgeList(Graph G, int source, int target, float peso){
if(G != NULL){
if(source != target){
if(source < G->nodes_count){
if(target < G->nodes_count)
((AdjList*)(G->adj))->nodes[source]= appendNodeList(((AdjList*)(G->adj))->nodes[source], target, peso);
else
fprintf(stderr, "Il nodo %d non e' compreso nel grafo\n", target);
}else
fprintf(stderr, "Il nodo %d non e' compreso nel grafo\n", source);
}else
fprintf(stderr, "Non e' possibile inserire un arco che punta allo stesso nodo\n");
}else
fprintf(stderr, "Grafo invalido\n");
}
List.h
struct TList {
char target;
float peso;
struct TList* next;
};
List initNodeList(int info, float peso);
List appendNodeList(List L, int target, float peso);
void printList(List L);
List.c
#include <stdio.h>
#include <stdlib.h>
#include "List.h"
List initNodeList(int info, float peso) {
List L = malloc(sizeof(struct TList));
L->target = info;
L->peso = peso;
L->next = NULL;
return L;
}
List appendNodeList(List L, int target, float peso) {
if (L != NULL) {
if (L->target != target) {
L->next = appendNodeList(L->next, target, peso);
}
} else {
L = initNodeList(target, peso);
}
return L;
}
void printList(List L) {
if (L != NULL) {
printf(" %c(%f), ", L->target + 'A', L->peso);
printList(L->next);
}
}
首先你忘了用 NULL 初始化你的指针数组。这是我在您的代码中发现的主要错误。
如果你使任何指针 typedef 避免误导名称(例如添加后缀
'Ptr' 到 typename)
typedef struct TList {
char target;
float peso;
struct TList* next;
} *TListPtr;
typedef struct TAdjList{
TListPtr *nodes;
} *TAdjListPtr;
不需要void **adj
。 TAdjListPtr *adj
为所欲为
typedef struct TGraph {
TAdjListPtr adj;
int nodes_count;
} *TGraphPtr;
TListPtr initNodeList(int info, float peso) {
TListPtr L = malloc(sizeof(struct TList));
L->target = info;
L->peso = peso;
L->next = NULL;
return L;
}
TListPtr appendNodeList(TListPtr L, int target, float peso) {
if (L != NULL) {
if (L->target != target) {
L->next = appendNodeList(L->next, target, peso);
}
} else {
L = initNodeList(target, peso);
}
return L;
}
void printList(TListPtr L) {
if (L != NULL) {
printf(" %c(%f), ", L->target + 'A', L->peso);
printList(L->next);
}
}
你必须用 NULL 初始化你的指针数组。为此使用 memset
。
TGraphPtr initGraphList(int nodes_count){
TGraphPtr G = malloc(sizeof(struct TGraph));
G->adj = malloc(sizeof(TAdjList));
G->nodes_count = nodes_count;
G->adj->nodes = (TListPtr*)malloc(nodes_count * sizeof(TListPtr));
memset( G->adj->nodes, 0, nodes_count * sizeof( TListPtr ) );
return G;
}
void printGraphList(TGraphPtr G) {
if (G != NULL) {
int i;
for(i = 0; i < G->nodes_count; i++) {
printf("%c -> ", i + 'A'); //I use this in order to print out the nodes as A,B,C,.. instead of 0,1,2,...
printList(G->adj->nodes[i] );
puts("\n");
}
}
}
void addEdgeList(TGraphPtr G, int source, int target, float peso){
if(G != NULL){
if(source != target){
if(source < G->nodes_count){
if(target < G->nodes_count)
G->adj->nodes[source] = appendNodeList(G->adj->nodes[source], target, peso);
else
fprintf(stderr, "Il nodo %d non e' compreso nel grafo\n", target);
}else
fprintf(stderr, "Il nodo %d non e' compreso nel grafo\n", source);
}else
fprintf(stderr, "Non e' possibile inserire un arco che punta allo stesso nodo\n");
}else
fprintf(stderr, "Grafo invalido\n");
}
消除编译器errors.and 警告后
但没有添加错误检查,这是结果。
注意::我没有检查此代码是否有任何未定义的行为
#include <stdio.h>
#include <stdlib.h>
struct TList
{
size_t target;
float peso;
struct TList* next;
};
//typedef struct TList * List;
struct TList * initNodeList(size_t info, float peso);
struct TList * appendNodeList(struct TList * L, size_t target, float peso);
void printList(struct TList * L);
struct TGraph
{
struct TList **nodes;
size_t nodes_count;
};
//typedef struct TGraph * Graph;
struct TGraph * initGraphList(size_t);
void printGraphList(struct TGraph *);
void addEdgeList(struct TGraph *, size_t, size_t, float);
int main( void )
{
struct TGraph * G = NULL;
G = initGraphList(3);
addEdgeList(G, 0, 1, 1);
addEdgeList(G, 0, 2, 2);
addEdgeList(G, 1, 0, 3);
addEdgeList(G, 1, 2, 4);
addEdgeList(G, 2, 0, 5);
addEdgeList(G, 2, 1, 6);
printGraphList(G);
return 0;
} // end function: main
struct TList * initNodeList(size_t info, float peso)
{
struct TList * L = malloc(sizeof(struct TList));
L->target = info;
L->peso = peso;
L->next = NULL;
return L;
} // end function: initNodeList
struct TList * appendNodeList(struct TList * L, size_t target, float peso)
{
if (L != NULL)
{
if (L->target != target)
{
L->next = appendNodeList(L->next, target, peso);
}
}
else
{
L = initNodeList(target, peso);
}
return L;
} // end function: appendNodeList
void printList(struct TList * L)
{
if (L != NULL)
{
printf(" %c(%f), ", (char)L->target + 'A', L->peso);
printList(L->next);
}
} // end function: printList
struct TGraph * initGraphList(size_t nodes_count)
{
struct TGraph * G = malloc(sizeof(struct TGraph));
G->nodes_count = nodes_count;
G->nodes = malloc(nodes_count * sizeof(struct TList *));
return G;
} // end function: initGraphList
void printGraphList(struct TGraph * G)
{
if (G != NULL)
{
for(size_t i = 0; i < G->nodes_count; i++)
{
printf("%c -> ", (char)i + 'A'); //I use this in order to print out the nodes as A,B,C,.. instead of 0,1,2,...
printList(G->nodes[i]);
puts("\n");
}
}
}
void addEdgeList(struct TGraph * G, size_t source, size_t target, float peso)
{
if(G != NULL)
{
if(source != target)
{
if(source < G->nodes_count)
{
if(target < G->nodes_count)
G->nodes[source]= appendNodeList(G->nodes[source], target, peso);
else
fprintf(stderr, "Il nodo %c non e' compreso nel grafo\n", (char)target);
}
else
fprintf(stderr, "Il nodo %c non e' compreso nel grafo\n", (char)source);
}
else
fprintf(stderr, "Non e' possibile inserire un arco che punta allo stesso nodo\n");
}
else
fprintf(stderr, "Grafo invalido\n");
}
输出为:
A -> B(1.000000), C(2.000000),
B -> A(3.000000), C(4.000000),
C -> A(5.000000), B(6.000000),
我正在尝试构建一个可以处理具有邻接列表或矩阵的图的程序,为此老师教我们将邻接声明为 void *,以便将其转换为列表或矩阵。
使用下面的代码我得到了这个输出:
如您所见,B 节点中存在一些奇怪的东西。
如果我尝试使用 CodeBlocks 进行调试,调试器会在 appendNodeList
at if (L->target != target) {..
Segmentation Fault
我认为 initGraphList
中的动态分配有问题,但我不知道如何解决它。
您认为这里的问题是什么?是分配吗?如果是,我该如何解决? 在此先感谢您的帮助!
代码:
main.c
#include <stdio.h>
#include <stdlib.h>
#include "Graph.h"
int main(int argc, const char * argv[]) {
Graph G = NULL;
G = initGraphList(3);
addEdgeList(G, 0, 1, 1);
addEdgeList(G, 0, 2, 2);
addEdgeList(G, 1, 0, 3);
addEdgeList(G, 1, 2, 4);
addEdgeList(G, 2, 0, 5);
addEdgeList(G, 2, 1, 6);
printGraphList(G);
return 0;
}
Graph.h
#include "List.h"
struct TGraph {
void **adj;
int nodes_count;
};
typedef struct TGraph *Graph;
typedef struct AdjList{
List *nodes;
}AdjList;
Graph initGraphList(int);
void printGraphList(Graph G);
void addEdgeList(Graph G, int source, int target, float peso);
Graph.c
#include <stdio.h>
#include <stdlib.h>
#include "Graph.h"
Graph initGraphList(int nodes_count){
Graph G = (Graph)malloc(sizeof(struct TGraph));
G->adj = malloc(sizeof(AdjList));
G->nodes_count = nodes_count;
((AdjList *)(G->adj))->nodes = malloc(nodes_count * sizeof(List));
return G;
}
void printGraphList(Graph G) {
if (G != NULL) {
int i;
for(i = 0; i < G->nodes_count; i++) {
printf("%c -> ", i + 'A'); //I use this in order to print out the nodes as A,B,C,.. instead of 0,1,2,...
printList(((AdjList *)(G->adj))->nodes[i]);
puts("\n");
}
}
}
void addEdgeList(Graph G, int source, int target, float peso){
if(G != NULL){
if(source != target){
if(source < G->nodes_count){
if(target < G->nodes_count)
((AdjList*)(G->adj))->nodes[source]= appendNodeList(((AdjList*)(G->adj))->nodes[source], target, peso);
else
fprintf(stderr, "Il nodo %d non e' compreso nel grafo\n", target);
}else
fprintf(stderr, "Il nodo %d non e' compreso nel grafo\n", source);
}else
fprintf(stderr, "Non e' possibile inserire un arco che punta allo stesso nodo\n");
}else
fprintf(stderr, "Grafo invalido\n");
}
List.h
struct TList {
char target;
float peso;
struct TList* next;
};
List initNodeList(int info, float peso);
List appendNodeList(List L, int target, float peso);
void printList(List L);
List.c
#include <stdio.h>
#include <stdlib.h>
#include "List.h"
List initNodeList(int info, float peso) {
List L = malloc(sizeof(struct TList));
L->target = info;
L->peso = peso;
L->next = NULL;
return L;
}
List appendNodeList(List L, int target, float peso) {
if (L != NULL) {
if (L->target != target) {
L->next = appendNodeList(L->next, target, peso);
}
} else {
L = initNodeList(target, peso);
}
return L;
}
void printList(List L) {
if (L != NULL) {
printf(" %c(%f), ", L->target + 'A', L->peso);
printList(L->next);
}
}
首先你忘了用 NULL 初始化你的指针数组。这是我在您的代码中发现的主要错误。
如果你使任何指针 typedef 避免误导名称(例如添加后缀 'Ptr' 到 typename)
typedef struct TList {
char target;
float peso;
struct TList* next;
} *TListPtr;
typedef struct TAdjList{
TListPtr *nodes;
} *TAdjListPtr;
不需要void **adj
。 TAdjListPtr *adj
为所欲为
typedef struct TGraph {
TAdjListPtr adj;
int nodes_count;
} *TGraphPtr;
TListPtr initNodeList(int info, float peso) {
TListPtr L = malloc(sizeof(struct TList));
L->target = info;
L->peso = peso;
L->next = NULL;
return L;
}
TListPtr appendNodeList(TListPtr L, int target, float peso) {
if (L != NULL) {
if (L->target != target) {
L->next = appendNodeList(L->next, target, peso);
}
} else {
L = initNodeList(target, peso);
}
return L;
}
void printList(TListPtr L) {
if (L != NULL) {
printf(" %c(%f), ", L->target + 'A', L->peso);
printList(L->next);
}
}
你必须用 NULL 初始化你的指针数组。为此使用 memset
。
TGraphPtr initGraphList(int nodes_count){
TGraphPtr G = malloc(sizeof(struct TGraph));
G->adj = malloc(sizeof(TAdjList));
G->nodes_count = nodes_count;
G->adj->nodes = (TListPtr*)malloc(nodes_count * sizeof(TListPtr));
memset( G->adj->nodes, 0, nodes_count * sizeof( TListPtr ) );
return G;
}
void printGraphList(TGraphPtr G) {
if (G != NULL) {
int i;
for(i = 0; i < G->nodes_count; i++) {
printf("%c -> ", i + 'A'); //I use this in order to print out the nodes as A,B,C,.. instead of 0,1,2,...
printList(G->adj->nodes[i] );
puts("\n");
}
}
}
void addEdgeList(TGraphPtr G, int source, int target, float peso){
if(G != NULL){
if(source != target){
if(source < G->nodes_count){
if(target < G->nodes_count)
G->adj->nodes[source] = appendNodeList(G->adj->nodes[source], target, peso);
else
fprintf(stderr, "Il nodo %d non e' compreso nel grafo\n", target);
}else
fprintf(stderr, "Il nodo %d non e' compreso nel grafo\n", source);
}else
fprintf(stderr, "Non e' possibile inserire un arco che punta allo stesso nodo\n");
}else
fprintf(stderr, "Grafo invalido\n");
}
消除编译器errors.and 警告后
但没有添加错误检查,这是结果。
注意::我没有检查此代码是否有任何未定义的行为
#include <stdio.h>
#include <stdlib.h>
struct TList
{
size_t target;
float peso;
struct TList* next;
};
//typedef struct TList * List;
struct TList * initNodeList(size_t info, float peso);
struct TList * appendNodeList(struct TList * L, size_t target, float peso);
void printList(struct TList * L);
struct TGraph
{
struct TList **nodes;
size_t nodes_count;
};
//typedef struct TGraph * Graph;
struct TGraph * initGraphList(size_t);
void printGraphList(struct TGraph *);
void addEdgeList(struct TGraph *, size_t, size_t, float);
int main( void )
{
struct TGraph * G = NULL;
G = initGraphList(3);
addEdgeList(G, 0, 1, 1);
addEdgeList(G, 0, 2, 2);
addEdgeList(G, 1, 0, 3);
addEdgeList(G, 1, 2, 4);
addEdgeList(G, 2, 0, 5);
addEdgeList(G, 2, 1, 6);
printGraphList(G);
return 0;
} // end function: main
struct TList * initNodeList(size_t info, float peso)
{
struct TList * L = malloc(sizeof(struct TList));
L->target = info;
L->peso = peso;
L->next = NULL;
return L;
} // end function: initNodeList
struct TList * appendNodeList(struct TList * L, size_t target, float peso)
{
if (L != NULL)
{
if (L->target != target)
{
L->next = appendNodeList(L->next, target, peso);
}
}
else
{
L = initNodeList(target, peso);
}
return L;
} // end function: appendNodeList
void printList(struct TList * L)
{
if (L != NULL)
{
printf(" %c(%f), ", (char)L->target + 'A', L->peso);
printList(L->next);
}
} // end function: printList
struct TGraph * initGraphList(size_t nodes_count)
{
struct TGraph * G = malloc(sizeof(struct TGraph));
G->nodes_count = nodes_count;
G->nodes = malloc(nodes_count * sizeof(struct TList *));
return G;
} // end function: initGraphList
void printGraphList(struct TGraph * G)
{
if (G != NULL)
{
for(size_t i = 0; i < G->nodes_count; i++)
{
printf("%c -> ", (char)i + 'A'); //I use this in order to print out the nodes as A,B,C,.. instead of 0,1,2,...
printList(G->nodes[i]);
puts("\n");
}
}
}
void addEdgeList(struct TGraph * G, size_t source, size_t target, float peso)
{
if(G != NULL)
{
if(source != target)
{
if(source < G->nodes_count)
{
if(target < G->nodes_count)
G->nodes[source]= appendNodeList(G->nodes[source], target, peso);
else
fprintf(stderr, "Il nodo %c non e' compreso nel grafo\n", (char)target);
}
else
fprintf(stderr, "Il nodo %c non e' compreso nel grafo\n", (char)source);
}
else
fprintf(stderr, "Non e' possibile inserire un arco che punta allo stesso nodo\n");
}
else
fprintf(stderr, "Grafo invalido\n");
}
输出为:
A -> B(1.000000), C(2.000000),
B -> A(3.000000), C(4.000000),
C -> A(5.000000), B(6.000000),