I have a working generic graph. The type for vertex is currently defined as:
typedef struct vertex { void *data; char *label; bool inGraph;} vertex;
The void pointer can then be customized for any algorithm, like BFS, DFS, etc. This works, but I want to simplify the code by using a separate header file for a vertex that specifies its type as needed, and is included in graph.h. Something like this:
#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 // defaulttypedef struct vertex { char *label; bool inGraph; } vertex;#endif#endif
This does not work, however. The right vertex type is not selected and allocated.
I have made an example to reproduce the issue.
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;}
graph.h
#ifndef GRAPH_H_INCLUDED#define GRAPH_H_INCLUDED#include <stdlib.h>#include "vertex.h"vertex *createVertex(char *label);void freeVertex(vertex *v);#endif
graph.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);}
The example works fine if I put a single definition in vertex.h. However, if I try to use the if directives, I get the following errors:
==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 ==986== Address 0x4a8e050 is 0 bytes after a block of size 16 alloc'd==986== at 0x484DA83: calloc ==986== by 0x109279: createVertex ==986== by 0x1090F5: main ==986====986== Invalid read of size 1==986== at 0x10913A: main ==986== Address 0x4a8e0f0 is 0 bytes after a block of size 16 alloc'd==986== at 0x484DA83: calloc ==986== by 0x109279: createVertex ==986== by 0x109108: main ==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 ==986== Address 0x4a8e0f0 is 0 bytes after a block of size 16 alloc'd==986== at 0x484DA83: calloc ==986== by 0x109279: createVertex ==986== by 0x109108: main ==986====986====986== 1 errors in context 2 of 2:==986== Invalid write of size 1==986== at 0x1090FD: main ==986== Address 0x4a8e050 is 0 bytes after a block of size 16 alloc'd==986== at 0x484DA83: calloc ==986== by 0x109279: createVertex ==986== by 0x1090F5: main ==986====986== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)