Valgrind内存泄漏指向localtime

3

我有这段代码:

#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));
}

当我对它使用valgrind时,我会得到以下警告:

==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)

虽然它们没有指向我的代码,但我仍然有泄漏。 我应该担心吗?

此外,如果您对我是否犯了任何错误或改进我的代码风格有任何建议,都非常感激!


1
指针:使用2行代码执行 return t.tv_sec + t.tv_usec*1e-6; - Tim
1
@Tim,请详细说明一下,我认为没有任何问题。 - drahnr
1
在单独的一行上进行计算,这样如果您在X行上出现错误,就更容易看出是什么原因导致的。 - Tim
1
+1 for abominable pun. - Nicholas Wilson
可能是重复的问题:Valgrind报告在OS X 10.8.1上存在内存泄漏 - Mike
3个回答

5
您正在使用最新版本的Valgrind 3.8.1。在不到一个完整版本之前(3.8.0),已支持OSX 10.8,但正如Valgrind的新闻页面所说
“对于MacOSX 10.8有初步支持,但目前无法进行严肃工作。”
版本3.8.0也减少了在MacOSX 10.6/10.7上的噪音(误报警告),但是对于10.8版本却没有这样的运气。我强烈建议您检查valgrind下载页面上的当前发布信息,您还可以从那里订阅最新版本的通知(带来更好的Mac OSX10.8支持)。
请注意:valgrind 3.7.0添加了对OSX 10.7的支持,因此您只需等待3.9版即可获得更好的支持。
至于“可能存在的内存泄漏”,您可以始终通过--show-possibly-lost=no标志压制这些警告,并暂时将Valgrind提供的所有信息视为不确定。
我指出的最后一页说:
“'可能丢失'意味着您的程序正在泄漏内存,除非您使用指针进行了不寻常的操作,这些操作可能导致它们指向已分配块的中间部分。请参阅用户手册以获取一些可能的原因。”
在新版Valgrind更好地支持OSX 10.8之前,我强烈建议您使用Oracle的VirtualBox与某些Linux发行版。您可以在其中运行您的代码,它是完全免费的,甚至有适用于OSX 10.8的版本。当我在我的Linux虚拟机中运行您的程序时,我看不到任何错误报告(请记住,我的版本略旧),所以很可能您只是遇到了误报警告。
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$ 

1

一般来说,您应该最担心的是definitely lost,这实际上取决于库。 Possibly lost有时会表明内存丢失,但实际上没有丢失,如果您使用复杂的数据类型和指针“嵌套”,转换和指针传递,则可能会发生这种情况。

另一个问题是,如果您正在处理图像并且问题出现在图像分配或取消分配中,可能会丢失很多字节,因此您应该担心,因为这可能会很快积累并根据您执行操作的频率而消耗您的内存。

另一方面,有些库需要您调用*_init函数,设置一些全局变量并永远不清除它们。 这是相当无害的。

您可以使用所谓的抑制文件使valgrind忽略这些问题。


在这种情况下,泄漏似乎来自valgrind而不是我的应用程序。还有需要担心的情况吗? - changelog
Valgrind本身告诉你,在OS X 10.8上它是不稳定的,而且大部分功能都无法正常工作。这很可能导致了错误的出现。 - slugonamission

0
我应该担心吗?
你应该担心valgrind在你的系统上无法正常工作吗?不用太担心;还有其他内存分析工具可以在你的系统上正常工作。
你应该担心你的程序是否存在内存泄漏吗?好吧,除非你使用一个能够正常工作的内存分析工具进行测试,否则你无法确定。
有任何指针可以告诉我是否我做错了什么吗?
是的,你做错了一些事情... Valgrind告诉你它在你的操作系统上大部分都失效了,但你在询问问题之前已经绕过了任何合理的程序员会采取的选项。
  1. 获取一个稳定的内存分析器(与您的操作系统兼容),而不是一个不稳定的,并使用该分析器验证泄漏情况(例如{{link1:/usr/bin/leaks/usr/bin/malloc_history},或“XCode Instruments”)。
  2. 如果没有可用的,可以在虚拟机中安装Linux或FreeBSD并在那里运行valgrind,这样它就会更加稳定。

如果您的问题有这两种选择之一的输出,它将不会显示警告,并且可能不会显示损坏/混乱的输出。也许它会指示您的程序没有泄漏,在这种情况下,您可以稍微放心一点,因为您的程序不太可能是泄漏内存的罪魁祸首。也许它会指示您的程序在函数xxx中泄漏内存,在函数中分配,在这种情况下,您可以稍微放心一点,因为您可以诊断和修复这些泄漏问题


那很痛,但这并不会让它变得不真实。谢谢。 - changelog
1
合理的程序员这个评价可能听起来有点严厉,但是依赖不稳定软件的输出是不可行的,所以这个建议不会伤害你。只需要在未来考虑所有选择,你就会发现自己做出更好的决定。顺便问一句,你考虑过调用 malloc 来分配 n 次节点(因此调用 malloc n 次)和调用 malloc 一次来分配 n 个节点之间的性能比较吗?如果你从 node_create 中消除 malloc(也许改为 node_init),你会发现这不是唯一的好处... - autistic
很抱歉,我不明白你在说什么。你能提供一个小的代码示例吗? - changelog

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接