Reputation: 4681
I have this code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/resource.h>
double get_time()
{
struct timeval t;
struct timezone tzp;
gettimeofday(&t, &tzp);
return t.tv_sec + t.tv_usec*1e-6;
}
#define LL_APPEND(what, where, type) { \
what->next = NULL; \
what->prev = NULL; \
if(!where) { \
where = what; \
} else { \
type current = where; \
while(current->next != NULL) \
current = current->next; \
current->next = what; \
what->prev = current; \
} \
}
struct edge {
struct node *from;
struct node *to;
char *label;
};
struct edge_list {
struct edge *edge;
struct edge_list *prev;
struct edge_list *next;
};
struct graph {
struct node_list *nodes;
struct edge_list *edges;
int nodes_count;
int edges_count;
};
struct node {
char *name;
struct edge_list *in;
struct edge_list *out;
struct graph *graph;
};
struct node_list {
struct node *node;
struct node_list *prev;
struct node_list *next;
};
struct graph *graph_create_empty() {
struct graph *graph = malloc(sizeof(struct graph));
graph->nodes = NULL;
graph->edges = NULL;
graph->nodes_count = 0;
graph->edges_count = 0;
return graph;
}
void edge_destroy(struct edge *edge) {
free(edge->label);
free(edge);
}
void node_destroy(struct node *node) {
struct edge_list *tmp_edge, *edge;
edge = node->in;
while(edge != NULL) {
tmp_edge = edge;
edge = edge->next;
free(tmp_edge);
}
edge = node->out;
while(edge != NULL) {
tmp_edge = edge;
edge = edge->next;
free(tmp_edge);
}
free(node->name);
free(node);
}
void graph_destroy(struct graph *graph) {
struct edge_list *tmp_edge, *edge;
edge = graph->edges;
while(edge != NULL) {
tmp_edge = edge;
edge = edge->next;
edge_destroy(tmp_edge->edge);
free(tmp_edge);
}
struct node_list *tmp_node, *node;
node = graph->nodes;
while(node != NULL) {
tmp_node = node;
node = node->next;
node_destroy(tmp_node->node);
free(tmp_node);
}
free(graph);
}
void graph_add_edge(struct graph *graph, struct edge *edge) {
struct edge_list *new_edge = malloc(sizeof(struct edge_list));
new_edge->edge = edge;
LL_APPEND(new_edge, graph->edges, struct edge_list *);
graph->edges_count++;
}
void graph_add_node(struct graph *graph, struct node *node) {
node->graph = graph;
struct node_list *new_node = malloc(sizeof(struct node_list));
new_node->node = node;
LL_APPEND(new_node, graph->nodes, struct node_list *);
graph->nodes_count++;
}
struct node *node_create(const char *name, struct graph *graph) {
struct node *node = malloc(sizeof(struct node));
node->name = malloc(strlen(name)+1);
strcpy(node->name, name);
node->in = NULL;
node->out = NULL;
if(graph)
graph_add_node(graph, node);
return node;
}
void node_add_edge(struct node *node, struct edge *edge) {
struct edge_list *new_edge = malloc(sizeof(struct edge_list));
if(node == edge->to) {
LL_APPEND(new_edge, node->out, struct edge_list *);
} else {
LL_APPEND(new_edge, node->in, struct edge_list *);
}
}
void node_connect(const char *label, struct node *from, struct node *to) {
if(from->graph != to->graph || from->graph == NULL)
return;
struct edge *edge = malloc(sizeof(struct edge));
edge->label = malloc(strlen(label)+1);
strcpy(edge->label, label);
edge->from = from;
edge->to = to;
graph_add_edge(from->graph, edge);
node_add_edge(from, edge);
node_add_edge(to, edge);
}
int main(int argc, char *argv[]) {
double start = get_time();
for(int i = 0; i < 100000; i++) {
struct graph *graph = graph_create_empty();
// Create the nodes
struct node *useful_demand_heat = node_create("useful_demand_heat", graph);
struct node *useful_demand_elec = node_create("useful_demand_elec", graph);
struct node *space_heater_coal = node_create("space_heater_coal", graph);
struct node *space_heater_gas = node_create("space_heater_gas", graph);
struct node *space_heater_oil = node_create("space_heater_oil", graph);
struct node *space_heater_chp = node_create("space_heater_chp", graph);
struct node *space_heater_elec = node_create("space_heater_elec", graph);
struct node *final_demand_coal = node_create("final_demand_coal", graph);
struct node *final_demand_gas = node_create("final_demand_gas", graph);
struct node *final_demand_oil = node_create("final_demand_oil", graph);
struct node *final_demand_elec = node_create("final_demand_elec", graph);
struct node *lv_network = node_create("lv_network", graph);
struct node *mv_network = node_create("mv_network", graph);
struct node *hv_network = node_create("hv_network", graph);
struct node *coal_plant = node_create("coal_plant", graph);
struct node *elec_import = node_create("elec_import", graph);
// Edges
node_connect("electricity", elec_import, hv_network);
node_connect("electricity", coal_plant, hv_network);
node_connect("electricity", hv_network, mv_network);
node_connect("electricity", mv_network, lv_network);
node_connect("electricity", lv_network, final_demand_elec);
node_connect("electricity", final_demand_elec, space_heater_elec);
node_connect("coal", final_demand_coal, space_heater_coal);
node_connect("gas", final_demand_gas, space_heater_gas);
node_connect("gas", final_demand_gas, space_heater_chp);
node_connect("oil", final_demand_oil, space_heater_oil);
node_connect("heat", space_heater_coal, useful_demand_heat);
node_connect("heat", space_heater_gas, useful_demand_heat);
node_connect("heat", space_heater_oil, useful_demand_heat);
node_connect("heat", space_heater_chp, useful_demand_heat);
node_connect("electricity", space_heater_chp, useful_demand_elec);
node_connect("electricity", space_heater_elec, useful_demand_elec);
graph_destroy(graph);
}
double finish = get_time();
printf("Took %.5f ms to run\n", (finish - start));
}
When I run valgrind against it, I get these warnings:
==44508== Memcheck, a memory error detector
==44508== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==44508== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==44508== Command: ./graph
==44508==
==44508== WARNING: Support on MacOS 10.8 is experimental and mostly broken.
==44508== WARNING: Expect incorrect results, assertions and crashes.
==44508== WARNING: In particular, Memcheck on 32-bit programs will fail to
==44508== WARNING: detect any errors associated with heap-allocated data.
==44508==
--44508-- ./graph:
--44508-- dSYM directory is missing; consider using --dsymutil=yes
Took 22.74883 ms to run
Done.
==44508==
==44508== HEAP SUMMARY:
==44508== in use at exit: 74,666 bytes in 365 blocks
==44508== total heap usage: 12,900,518 allocs, 12,900,153 frees, 284,078,620 bytes allocated
==44508==
==44508== 16 bytes in 1 blocks are definitely lost in loss record 7 of 88
==44508== at 0x54D7: malloc_zone_malloc (in /usr/local/Cellar/valgrind/3.8.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==44508== by 0x373381: recursive_mutex_init (in /usr/lib/libobjc.A.dylib)
==44508== by 0x372025: _objc_init (in /usr/lib/libobjc.A.dylib)
==44508== by 0xBB27: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==44508== by 0x7FFF5FC13377: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==44508== by 0x7FFF5FC13761: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==44508== by 0x7FFF5FC1006D: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==44508== by 0x7FFF5FC0FFC3: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==44508== by 0x7FFF5FC0FEB9: ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==44508== by 0x7FFF5FC01F9D: dyld::initializeMainExecutable() (in /usr/lib/dyld)
==44508== by 0x7FFF5FC05B03: dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**, unsigned long*) (in /usr/lib/dyld)
==44508== by 0x7FFF5FC01396: dyldbootstrap::start(macho_header const*, int, char const**, long, macho_header const*, unsigned long*) (in /usr/lib/dyld)
==44508==
==44508== 32 bytes in 1 blocks are possibly lost in loss record 24 of 88
==44508== at 0x5A95: malloc_zone_calloc (in /usr/local/Cellar/valgrind/3.8.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==44508== by 0x3756EA: NXHashInsert (in /usr/lib/libobjc.A.dylib)
==44508== by 0x37546C: NXCreateHashTableFromZone (in /usr/lib/libobjc.A.dylib)
==44508== by 0x374788: _read_images (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3739EB: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3734F3: map_images (in /usr/lib/libobjc.A.dylib)
==44508== by 0x7FFF5FC04936: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)) (in /usr/lib/dyld)
==44508== by 0x7FFF5FC0467C: dyld::registerImageStateBatchChangeHandler(dyld_image_states, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)) (in /usr/lib/dyld)
==44508== by 0x83ED9: dyld_register_image_state_change_handler (in /usr/lib/system/libdyld.dylib)
==44508== by 0x37204C: _objc_init (in /usr/lib/libobjc.A.dylib)
==44508== by 0xBB27: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==44508== by 0x7FFF5FC13377: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==44508==
==44508== 64 bytes in 2 blocks are possibly lost in loss record 36 of 88
==44508== at 0x5A95: malloc_zone_calloc (in /usr/local/Cellar/valgrind/3.8.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==44508== by 0x3756EA: NXHashInsert (in /usr/lib/libobjc.A.dylib)
==44508== by 0x385324: realizeClass(class_t*) (in /usr/lib/libobjc.A.dylib)
==44508== by 0x374E9C: _read_images (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3739EB: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3734F3: map_images (in /usr/lib/libobjc.A.dylib)
==44508== by 0x7FFF5FC04936: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)) (in /usr/lib/dyld)
==44508== by 0x7FFF5FC0467C: dyld::registerImageStateBatchChangeHandler(dyld_image_states, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)) (in /usr/lib/dyld)
==44508== by 0x83ED9: dyld_register_image_state_change_handler (in /usr/lib/system/libdyld.dylib)
==44508== by 0x37204C: _objc_init (in /usr/lib/libobjc.A.dylib)
==44508== by 0xBB27: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==44508== by 0x7FFF5FC13377: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==44508==
==44508== 64 bytes in 2 blocks are possibly lost in loss record 37 of 88
==44508== at 0x5A95: malloc_zone_calloc (in /usr/local/Cellar/valgrind/3.8.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==44508== by 0x3756EA: NXHashInsert (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3757F6: _NXHashRehashToCapacity (in /usr/lib/libobjc.A.dylib)
==44508== by 0x375748: NXHashInsert (in /usr/lib/libobjc.A.dylib)
==44508== by 0x385324: realizeClass(class_t*) (in /usr/lib/libobjc.A.dylib)
==44508== by 0x374E9C: _read_images (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3739EB: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3734F3: map_images (in /usr/lib/libobjc.A.dylib)
==44508== by 0x7FFF5FC04936: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)) (in /usr/lib/dyld)
==44508== by 0x7FFF5FC0467C: dyld::registerImageStateBatchChangeHandler(dyld_image_states, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)) (in /usr/lib/dyld)
==44508== by 0x83ED9: dyld_register_image_state_change_handler (in /usr/lib/system/libdyld.dylib)
==44508== by 0x37204C: _objc_init (in /usr/lib/libobjc.A.dylib)
==44508==
==44508== 64 bytes in 1 blocks are definitely lost in loss record 38 of 88
==44508== at 0x54D7: malloc_zone_malloc (in /usr/local/Cellar/valgrind/3.8.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==44508== by 0x3733CF: recursive_mutex_init (in /usr/lib/libobjc.A.dylib)
==44508== by 0x372025: _objc_init (in /usr/lib/libobjc.A.dylib)
==44508== by 0xBB27: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==44508== by 0x7FFF5FC13377: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==44508== by 0x7FFF5FC13761: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==44508== by 0x7FFF5FC1006D: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==44508== by 0x7FFF5FC0FFC3: ImageLoader::recursiveInitialization(ImageLoader::LinkContext const&, unsigned int, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==44508== by 0x7FFF5FC0FEB9: ImageLoader::runInitializers(ImageLoader::LinkContext const&, ImageLoader::InitializerTimingList&) (in /usr/lib/dyld)
==44508== by 0x7FFF5FC01F9D: dyld::initializeMainExecutable() (in /usr/lib/dyld)
==44508== by 0x7FFF5FC05B03: dyld::_main(macho_header const*, unsigned long, int, char const**, char const**, char const**, unsigned long*) (in /usr/lib/dyld)
==44508== by 0x7FFF5FC01396: dyldbootstrap::start(macho_header const*, int, char const**, long, macho_header const*, unsigned long*) (in /usr/lib/dyld)
==44508==
==44508== 72 (24 direct, 48 indirect) bytes in 1 blocks are definitely lost in loss record 39 of 88
==44508== at 0x5A95: malloc_zone_calloc (in /usr/local/Cellar/valgrind/3.8.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==44508== by 0x3796D2: _objc_fetch_pthread_data (in /usr/lib/libobjc.A.dylib)
==44508== by 0x382C4D: _fetchInitializingClassList(signed char) (in /usr/lib/libobjc.A.dylib)
==44508== by 0x379181: _class_initialize (in /usr/lib/libobjc.A.dylib)
==44508== by 0x379137: _class_initialize (in /usr/lib/libobjc.A.dylib)
==44508== by 0x379137: _class_initialize (in /usr/lib/libobjc.A.dylib)
==44508== by 0x379137: _class_initialize (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3790F2: prepareForMethodLookup (in /usr/lib/libobjc.A.dylib)
==44508== by 0x378EEE: lookUpMethod (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3772FB: objc_msgSend (in /usr/lib/libobjc.A.dylib)
==44508== by 0x2DEE87: _libxpc_initializer (in /usr/lib/system/libxpc.dylib)
==44508== by 0xBB2C: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==44508==
==44508== 96 bytes in 3 blocks are possibly lost in loss record 43 of 88
==44508== at 0x5A95: malloc_zone_calloc (in /usr/local/Cellar/valgrind/3.8.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==44508== by 0x3756EA: NXHashInsert (in /usr/lib/libobjc.A.dylib)
==44508== by 0x38533D: realizeClass(class_t*) (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3845D0: realizeClass(class_t*) (in /usr/lib/libobjc.A.dylib)
==44508== by 0x374E9C: _read_images (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3739EB: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3734F3: map_images (in /usr/lib/libobjc.A.dylib)
==44508== by 0x7FFF5FC04936: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)) (in /usr/lib/dyld)
==44508== by 0x7FFF5FC0467C: dyld::registerImageStateBatchChangeHandler(dyld_image_states, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)) (in /usr/lib/dyld)
==44508== by 0x83ED9: dyld_register_image_state_change_handler (in /usr/lib/system/libdyld.dylib)
==44508== by 0x37204C: _objc_init (in /usr/lib/libobjc.A.dylib)
==44508== by 0xBB27: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==44508==
==44508== 96 bytes in 3 blocks are possibly lost in loss record 44 of 88
==44508== at 0x5A95: malloc_zone_calloc (in /usr/local/Cellar/valgrind/3.8.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==44508== by 0x3756EA: NXHashInsert (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3757F6: _NXHashRehashToCapacity (in /usr/lib/libobjc.A.dylib)
==44508== by 0x375748: NXHashInsert (in /usr/lib/libobjc.A.dylib)
==44508== by 0x38533D: realizeClass(class_t*) (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3845D0: realizeClass(class_t*) (in /usr/lib/libobjc.A.dylib)
==44508== by 0x374E9C: _read_images (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3739EB: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3734F3: map_images (in /usr/lib/libobjc.A.dylib)
==44508== by 0x7FFF5FC04936: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)) (in /usr/lib/dyld)
==44508== by 0x7FFF5FC0467C: dyld::registerImageStateBatchChangeHandler(dyld_image_states, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)) (in /usr/lib/dyld)
==44508== by 0x83ED9: dyld_register_image_state_change_handler (in /usr/lib/system/libdyld.dylib)
==44508==
==44508== 120 bytes in 5 blocks are possibly lost in loss record 47 of 88
==44508== at 0x5A95: malloc_zone_calloc (in /usr/local/Cellar/valgrind/3.8.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==44508== by 0x37566D: NXHashInsert (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3757F6: _NXHashRehashToCapacity (in /usr/lib/libobjc.A.dylib)
==44508== by 0x375748: NXHashInsert (in /usr/lib/libobjc.A.dylib)
==44508== by 0x38533D: realizeClass(class_t*) (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3845D0: realizeClass(class_t*) (in /usr/lib/libobjc.A.dylib)
==44508== by 0x374E9C: _read_images (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3739EB: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3734F3: map_images (in /usr/lib/libobjc.A.dylib)
==44508== by 0x7FFF5FC04936: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)) (in /usr/lib/dyld)
==44508== by 0x7FFF5FC0467C: dyld::registerImageStateBatchChangeHandler(dyld_image_states, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)) (in /usr/lib/dyld)
==44508== by 0x83ED9: dyld_register_image_state_change_handler (in /usr/lib/system/libdyld.dylib)
==44508==
...
==44508== 8,192 bytes in 8 blocks are definitely lost in loss record 86 of 88
==44508== at 0x54D7: malloc_zone_malloc (in /usr/local/Cellar/valgrind/3.8.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==44508== by 0x3745AE: objc::DenseMap<objc_object*, unsigned long, true, objc::DenseMapInfo<objc_object*>, objc::DenseMapInfo<unsigned long> >::init(unsigned int) (in /usr/lib/libobjc.A.dylib)
==44508== by 0x37455A: arr_init (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3739DF: map_images_nolock (in /usr/lib/libobjc.A.dylib)
==44508== by 0x3734F3: map_images (in /usr/lib/libobjc.A.dylib)
==44508== by 0x7FFF5FC04936: dyld::notifyBatchPartial(dyld_image_states, bool, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)) (in /usr/lib/dyld)
==44508== by 0x7FFF5FC0467C: dyld::registerImageStateBatchChangeHandler(dyld_image_states, char const* (*)(dyld_image_states, unsigned int, dyld_image_info const*)) (in /usr/lib/dyld)
==44508== by 0x83ED9: dyld_register_image_state_change_handler (in /usr/lib/system/libdyld.dylib)
==44508== by 0x37204C: _objc_init (in /usr/lib/libobjc.A.dylib)
==44508== by 0xBB27: libSystem_initializer (in /usr/lib/libSystem.B.dylib)
==44508== by 0x7FFF5FC13377: ImageLoaderMachO::doModInitFunctions(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==44508== by 0x7FFF5FC13761: ImageLoaderMachO::doInitialization(ImageLoader::LinkContext const&) (in /usr/lib/dyld)
==44508==
==44508== 10,808 bytes in 1 blocks are possibly lost in loss record 87 of 88
==44508== at 0x5237: malloc (in /usr/local/Cellar/valgrind/3.8.1/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==44508== by 0x101745: tzsetwall_basic (in /usr/lib/system/libsystem_c.dylib)
==44508== by 0x103043: localtime (in /usr/lib/system/libsystem_c.dylib)
==44508== by 0xFB52C: gettimeofday (in /usr/lib/system/libsystem_c.dylib)
==44508== by 0x1000017A0: main (in ./graph)
==44508==
==44508== LEAK SUMMARY:
==44508== definitely lost: 9,729 bytes in 16 blocks
==44508== indirectly lost: 1,236 bytes in 7 blocks
==44508== possibly lost: 15,749 bytes in 68 blocks
==44508== still reachable: 47,952 bytes in 274 blocks
==44508== suppressed: 0 bytes in 0 blocks
==44508== Reachable blocks (those to which a pointer was found) are not shown.
==44508== To see them, rerun with: --leak-check=full --show-reachable=yes
==44508==
==44508== For counts of detected and suppressed errors, rerun with: -v
==44508== ERROR SUMMARY: 22 errors from 22 contexts (suppressed: 0 from 0)
They don't point to my code, but I still have leaks. Should I be worried?
(also, any pointers (see what I did there?) as to if I'm doing anything wrong or improving my code style are much appreciated!)
Upvotes: 3
Views: 1497
Reputation: 6886
I general you should be most worried about the definitely lost
and it really depends on the library. Possibly lost
sometimes indicates memory being lost, but actually none is, this can happen if you have complex datatypes and use pointer "nesting", casting and pointer passing.
Another point is, if you are working with images and the issue is within image allocation or de-allocation a lot of bytes (may) get lost, thus you should worry, as that might accumulate quite quickly and eat up your memory depending on how frequently you do that.
On the other hand side there are libraries that require you to call *_init
function, which set up some global variables and never clean them up. That is quite harmless.
You can make valgrind blend out these with so called supression-files.
Upvotes: 1
Reputation: 15642
Should I be worried?
Should you be worried that valgrind doesn't work correctly on your system? Not really; There are other memory profilers that will work correctly on your system.
Should you be worried that your program leaks memory? Well, you won't know for certain until you test it with a memory profiler that works correctly.
... any pointers ... as to if I'm doing anything wrong ...
Yes, you're doing something wrong... Valgrind is telling you that it's mostly broken on your OS, and yet you've somehow bypassed all of the options any reasonable programmer would take, before asking a question here:
/usr/bin/leaks
and /usr/bin/malloc_history
, or "XCode Instruments").If your question had output from one of these two alternatives, it wouldn't display that warning and it might not display broken/confusing output. Perhaps it would indicate that your program has no leaks, in which case you can be a little less worried because it's less likely that your program is to blame for leaking memory. Perhaps it would indicate that your program leaks memory in function xxx, allocated in function, in which case you can be a little less worried because you can diagnose and fix those leaks, yourself!
Upvotes: 0
Reputation: 49463
You're using 3.8.1 of Valgrind, which is the latest and greatest. Support for OSX 10.8 was brought in less than a full version ago (3.8.0) and as valgrind's news page says:
There is initial support for MacOSX 10.8, but it is not usable for serious work at present.
The 3.8.0 version also Reduced noise (false positive) level on MacOSX 10.6/10.7
but no such luck for 10.8. I highly recommend checking the current releases on the valgrind download page you can also subscribe from there for notifications of the newest releases (which should bring in better support for Mac OSX10.8)
Note: valgrind 3.7.0 added support for OSX 10.7 so you probably only have to wait for 3.9 to come out to get better support.
As far as "possible memory leaks" go, you can always suppress these warnings with the --show-possibly-lost=no
flag, and for now take everything valgrind gives you with a grain of salt.
That last page I pointed you to says:
"possibly lost" means your program is leaking memory, unless you're doing unusual things with pointers that could cause them to point into the middle of an allocated block; see the user manual for some possible causes.
Until a new version of valgrind comes out that better supports OSX 10.8 I highly recommend using Oracle's VirtualBox with some Linux distro, you can run your code in there and it's all free, there's even a version for OSX 10.8. When I run your program on my Linux virtualbox I see no errors reported, (keep in mind I have a slightly older version) so odds are good that you're just seeing false positives:
mike@mike-VirtualBox:~/C$ valgrind ./a.out
==12465== Memcheck, a memory error detector
==12465== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==12465== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==12465== Command: ./a.out
==12465==
Took 43.77033 ms to run
==12465==
==12465== HEAP SUMMARY:
==12465== in use at exit: 0 bytes in 0 blocks
==12465== total heap usage: 12,900,000 allocs, 12,900,000 frees, 284,000,000 bytes allocated
==12465==
==12465== All heap blocks were freed -- no leaks are possible
==12465==
==12465== For counts of detected and suppressed errors, rerun with: -v
==12465== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
mike@mike-VirtualBox:~/C$
Upvotes: 5