我有一个可用的通用图表。顶点的类型当前定义为:
typedef struct vertex {
void *data;
char *label;
bool inGraph;
} vertex;
然后可以为任何算法自定义 void 指针,例如 BFS、DFS 等。这是可行的,但我想通过为顶点使用单独的头文件来简化代码,该顶点根据需要指定其类型,并包含在图中。H。像这样的东西:
#ifndef VERTEX_H_INCLUDED
#define VERTEX_H_INCLUDED
#include <stdlib.h>
#include <stdbool.h>
#if defined (GRAPH_VERTEX1)
typedef struct vertex {
struct vertex *parent;
char *label;
bool inGraph;
} vertex;
#elif defined (GRAPH_VERTEX2)
typedef struct vertex {
size_t dist;
char *label;
bool inGraph;
} vertex;
#else // default
typedef struct vertex {
char *label;
bool inGraph;
} vertex;
#endif
#endif
然而,这不起作用。未选择和分配正确的顶点类型。我做了一个例子来重现这个问题。
main.c
#include <stdio.h>
#define GRAPH_VERTEX1
#include "graph.h"
int main() {
vertex *v = createVertex("test");
v->inGraph = true;
vertex *parent = createVertex("parent");
printf("Vertex: %s\n", v->label);
printf("Parent: %s\n", parent->label);
printf("In graph: %d\n", parent->inGraph);
freeVertex(v);
freeVertex(parent);
return 0;
}
图.h
#ifndef GRAPH_H_INCLUDED
#define GRAPH_H_INCLUDED
#include <stdlib.h>
#include "vertex.h"
vertex *createVertex(char *label);
void freeVertex(vertex *v);
#endif
图.c
#include "graph.h"
#include <string.h>
vertex *createVertex(char *label) {
vertex *v = calloc(1, sizeof(vertex));
v->label = calloc(strlen(label) + 1, sizeof(char));
v->inGraph = false;
strcpy(v->label, label);
return v;
}
void freeVertex(vertex *v) {
free(v->label);
free(v);
}
如果我在 vertex.h 中放置单个定义,则该示例可以正常工作。但是,如果我尝试使用 if 指令,我会收到以下错误:
==986== Memcheck, a memory error detector
==986== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==986== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==986== Command: ./a.out
==986==
==986== Invalid write of size 1
==986== at 0x1090FD: main (in /mnt/d/Dropbox/Programs/pubgithub/CLRS/datastructures/graphs/dgraph/a.out)
==986== Address 0x4a8e050 is 0 bytes after a block of size 16 alloc'd
==986== at 0x484DA83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==986== by 0x109279: createVertex (in /mnt/d/Dropbox/Programs/pubgithub/CLRS/datastructures/graphs/dgraph/a.out)
==986== by 0x1090F5: main (in /mnt/d/Dropbox/Programs/pubgithub/CLRS/datastructures/graphs/dgraph/a.out)
==986==
==986== Invalid read of size 1
==986== at 0x10913A: main (in /mnt/d/Dropbox/Programs/pubgithub/CLRS/datastructures/graphs/dgraph/a.out)
==986== Address 0x4a8e0f0 is 0 bytes after a block of size 16 alloc'd
==986== at 0x484DA83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==986== by 0x109279: createVertex (in /mnt/d/Dropbox/Programs/pubgithub/CLRS/datastructures/graphs/dgraph/a.out)
==986== by 0x109108: main (in /mnt/d/Dropbox/Programs/pubgithub/CLRS/datastructures/graphs/dgraph/a.out)
==986==
Vertex: (null)
Parent: (null)
In graph: 0
==986==
==986== HEAP SUMMARY:
==986== in use at exit: 0 bytes in 0 blocks
==986== total heap usage: 5 allocs, 5 frees, 4,140 bytes allocated
==986==
==986== All heap blocks were freed -- no leaks are possible
==986==
==986== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
==986==
==986== 1 errors in context 1 of 2:
==986== Invalid read of size 1
==986== at 0x10913A: main (in /mnt/d/Dropbox/Programs/pubgithub/CLRS/datastructures/graphs/dgraph/a.out)
==986== Address 0x4a8e0f0 is 0 bytes after a block of size 16 alloc'd
==986== at 0x484DA83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==986== by 0x109279: createVertex (in /mnt/d/Dropbox/Programs/pubgithub/CLRS/datastructures/graphs/dgraph/a.out)
==986== by 0x109108: main (in /mnt/d/Dropbox/Programs/pubgithub/CLRS/datastructures/graphs/dgraph/a.out)
==986==
==986==
==986== 1 errors in context 2 of 2:
==986== Invalid write of size 1
==986== at 0x1090FD: main (in /mnt/d/Dropbox/Programs/pubgithub/CLRS/datastructures/graphs/dgraph/a.out)
==986== Address 0x4a8e050 is 0 bytes after a block of size 16 alloc'd
==986== at 0x484DA83: calloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so)
==986== by 0x109279: createVertex (in /mnt/d/Dropbox/Programs/pubgithub/CLRS/datastructures/graphs/dgraph/a.out)
==986== by 0x1090F5: main (in /mnt/d/Dropbox/Programs/pubgithub/CLRS/datastructures/graphs/dgraph/a.out)
==986==
==986== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
graph.c
需要具有与
#define GRAPH_VERTEX1
中相同的
main.c
- 否则使用的翻译将获得默认的
vertex
定义(因为
GRAPH_VERTEX1
和
GRAPH_VERTEX2
都不会被定义)。您可以将
#define GRAPH_VERTEX1
放入单独的头文件中,并从
main.c
和
graph.c
中包含该头文件:
#ifndef SOMENAME_H
#define SOMENAME_H
#define GRAPH_VERTEX1
#include "graph.h"
#endif
...或者只是将其放在graph.h
的顶部。