Deutsch   English   Français   Italiano  
<j8idnQlHTPZXZFv7nZ2dnZfqn_GdnZ2d@brightview.co.uk>

View for Bookmarking (what is this?)
Look up another Usenet article

Path: ...!Xl.tags.giganews.com!local-4.nntp.ord.giganews.com!nntp.brightview.co.uk!news.brightview.co.uk.POSTED!not-for-mail
NNTP-Posting-Date: Thu, 22 Aug 2024 08:41:46 +0000
From: Mark Summerfield <mark@qtrac.eu>
Subject: valgrind leak I can't find
Newsgroups: comp.lang.c
MIME-Version: 1.0
User-Agent: Pan/0.154 (Izium; 517acf4)
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Message-ID: <j8idnQlHTPZXZFv7nZ2dnZfqn_GdnZ2d@brightview.co.uk>
Date: Thu, 22 Aug 2024 08:41:46 +0000
Lines: 81
X-Usenet-Provider: http://www.giganews.com
X-Trace: sv3-fb1Wi8NpMoO5KrJWtouNmc86quVvqJgl0gz2hmmNnP5+Ez7WCKZWdar/AgyTb61Y9lqgp6pB+/xz92j!bDnVUkcBytGbGo1bofO1Y0omqW5xibPR8mvp9jDef2JIMTQxuaE42Rjp/qZ+xvp2CzPeK/ErAjmB!OGD01GMXOIjzlXbIkPcrghpiIQ==
X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers
X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly
X-Postfilter: 1.3.40
Bytes: 3500

valgrind tells me that I have memory leaks.

Its summary:

valgrind ./cx_test 
==18053== Memcheck, a memory error detector
==18053== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==18053== Using Valgrind-3.19.0 and LibVEX; rerun with -h for copyright info
==18053== Command: ./cx_test
==18053== 
OK 788/788
==18053== 
==18053== HEAP SUMMARY:
==18053==     in use at exit: 841 bytes in 50 blocks
==18053==   total heap usage: 2,323,773 allocs, 2,323,723 frees, 65,066,770 bytes allocated
==18053== 
==18053== LEAK SUMMARY:
==18053==    definitely lost: 841 bytes in 50 blocks
==18053==    indirectly lost: 0 bytes in 0 blocks
==18053==      possibly lost: 0 bytes in 0 blocks
==18053==    still reachable: 0 bytes in 0 blocks
==18053==         suppressed: 0 bytes in 0 blocks
==18053== Rerun with --leak-check=full to see details of leaked memory
==18053== 
==18053== For lists of detected and suppressed errors, rerun with: -s
==18053== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

The first leak in the detailed report is this:

==18005== 5 bytes in 1 blocks are definitely lost in loss record 1 of 25
==18005==    at 0x48407B4: malloc (vg_replace_malloc.c:381)
==18005==    by 0x49E38E9: strdup (strdup.c:42)
==18005==    by 0x10CAD4: vec_str_tests (vec_str_test.c:77)
==18005==    by 0x109346: main (cx_test.c:26)

vec_str_test.c:77 is:

    vec_str_insert(&v1, 4, strdup("beta"));

The reason I use strdup() is because my VecStr type takes ownership of
the strings it holds.

This is the type's struct:

typedef struct {
    int _size;
    int _cap;
    char** _values;
} VecStr;

Here is the vec_str_insert() function:

void vec_str_insert(VecStr* vec, int index, char* value) {
    assert_notnull(vec);
    assert_notnull(value);
    if (index == vec->_size) { // add at the end
        vec_str_push(vec, value);
        return;
    }
    assert_valid_index(vec, index);
    if (vec->_size == vec->_cap)
        vec_str_grow(vec);
    for (int i = vec->_size; i > index; --i)
        vec->_values[i] = vec->_values[i - 1];
    vec->_values[index] = value;
    vec->_size++;
}

And here is the grow() function it uses:

static void vec_str_grow(VecStr* vec) {
    const int BLOCK_SIZE = 1024 * 1024;
    int cap =
        (vec->_cap < BLOCK_SIZE) ? vec->_cap * 2 : vec->_cap + BLOCK_SIZE;
    char** p = realloc(vec->_values, cap * sizeof(char*));
    assert_alloc(p);
    vec->_values = p;
    vec->_cap = cap;
}

I can't see what I've done wrong.