Deutsch   English   Français   Italiano  
<oKScnQbmXbeW5Fr7nZ2dnZfqn_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 17:44:43 +0000
From: Mark Summerfield <mark@qtrac.eu>
Subject: Re: valgrind leak I can't find
Newsgroups: comp.lang.c
References: <j8idnQlHTPZXZFv7nZ2dnZfqn_GdnZ2d@brightview.co.uk>
MIME-Version: 1.0
User-Agent: Pan/0.149 (Bellevue; 4c157ba)
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Message-ID: <oKScnQbmXbeW5Fr7nZ2dnZfqn_GdnZ2d@brightview.co.uk>
Date: Thu, 22 Aug 2024 17:44:43 +0000
Lines: 42
X-Usenet-Provider: http://www.giganews.com
X-Trace: sv3-5tn3Bd75zOxoPuzqwrghMZS2VXkd6IcKVe6PuM8V3OC5qap+q1te9mLqMBXfRLg432nPK0Cenq6gI5k!6zUZOqWQG3nlxy2Ou6bS58paIrGcmnN38QkhrXd/HRRkJrys4gO7s0IQ3ieuVqw3sx0iR5A/7mKs!RGsaKc4Jl+mrzri9+xyH4FjHvg==
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: 2258

Thank you to all who replied.

TL;DR The problem turned out to be a double-free because I had two owning
collections with the same strings. I've now made VecStr and SetStr able to
be owning or nonowning and this valgrind leak has gone.

- I don't want to post the code since it is just for me relearning C.
  (I'm creating a tiny collections lib: Vec (of void*), VecStr, VecInt,
  SetInt, SetStr.)

- The reason I special cased when index == vec->_size is that I did a
  needless premature "optimization": I no longer do this.

- I use underscores for some struct fields. For the collections I provide
  functions for their APIs but of course the fields are not private so I use
  the underscore in a Python-like way to remind myself they are "private".

- Yes, I free as needed:

typedef struct {
    int _size;
    int _cap;
    char** _values;
    bool _owns; // new
} VecStr;

void vec_str_free(VecStr* vec) {
    assert_notnull(vec);
    vec_str_clear(vec);
    free(vec->_values);
    vec->_values = NULL;
    vec->_cap = 0;
}

void vec_str_clear(VecStr* vec) {
    assert_notnull(vec);
    if (vec->_owns)
        for (int i = 0; i < vec->_size; ++i)
            free(vec->_values[i]);
    vec->_size = 0;
}