valgrind tells me that I have memory leaks.
Here is the vec_str_insert() function:
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++;
}
vec->_values[index] = value;
assert_alloc(p);
On 22/08/2024 08:01, Bart wrote:
On 22/08/2024 09:41, Mark Summerfield wrote:
This is the type's struct:
typedef struct {
int _size;
int _cap;
char** _values;
} VecStr;
What's with the leading underscores for member names?
It means ending with ->_ later on, which seems pointless extra
clutter.
C++ is responsible for this.
C++ made the usage of 'this->' optional when calling member
functions.
As a result, when C++ programmers encounter 'i' in the middle of a
function, they might not know where it comes from.
If 'this->' were not optional, 'this->i' would clarify that.
To avoid confusion, many C++ programmers use prefixes like 'm_' that
can't be ignored.
Since many C programmers also work in C++, this pattern can sometimes influence C code as well.
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.
Thank you to all who replied.
TL;DR The problem turned out to be a double-free because I had two owning
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.)
Mark Summerfield <mark@qtrac.eu> wrote or quoted:
I don't want to post the code since it is just for me relearning C.
It's totally your prerogative if you wanna keep your code
on the down-low. No need to spill the beans.
But just to cut through the fog in your logic, your "since" reasoning
is a bit of a brain-bender: If I'm cranking out some code to sharpen
my C chops, that's no reason to bury it six feet under later on.
(I'm creating a tiny collections lib: Vec (of void*), VecStr, VecInt,
SetInt, SetStr.)
Yeah, for sure. But we got to wonder if these are really
meat-and-potatoes C problems . . .
Scope out what C was cooked up for in the first place. Eyeball
those vintage UNIX source files: "find.c", "echo.c", "tar.c",
"ls.c", "zork.c", "tail.c", and all that noise. How many of
those kick off with a container library?
What gnarly waves are you missing out on in efficient and
idiomatic C programming by thinking, "I'll use my container
library and write C like it's some Silicon Valley startup code!"
On 23/08/2024 12:03, Stefan Ram wrote:
Mark Summerfield <mark@qtrac.eu> wrote or quoted:
I don't want to post the code since it is just for me relearning
C.
It's totally your prerogative if you wanna keep your code
on the down-low. No need to spill the beans.
But just to cut through the fog in your logic, your "since"
reasoning is a bit of a brain-bender: If I'm cranking out some code
to sharpen my C chops, that's no reason to bury it six feet under
later on.
(I'm creating a tiny collections lib: Vec (of void*), VecStr,
VecInt, SetInt, SetStr.)
Yeah, for sure. But we got to wonder if these are really
meat-and-potatoes C problems . . .
Scope out what C was cooked up for in the first place. Eyeball
those vintage UNIX source files: "find.c", "echo.c", "tar.c",
"ls.c", "zork.c", "tail.c", and all that noise. How many of
those kick off with a container library?
What gnarly waves are you missing out on in efficient and
idiomatic C programming by thinking, "I'll use my container
library and write C like it's some Silicon Valley startup code!"
So, what have you done with the real Stefan Ram?
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.
On Fri, 23 Aug 2024 12:18:38 +0100
Bart <bc@freeuk.com> wrote:
So, what have you done with the real Stefan Ram?
It looks like real Stephan Ram hatched out of old restrictive eggshell
few months ago.
BTW, in order to compare his writing style of old with the new one, I
tried to look for his posts on Google Groups. It turned out that I can
only see citations. Posts themselves are not archived. Mysterious.
On Fri, 23 Aug 2024 12:18:38 +0100...
Bart <bc@freeuk.com> wrote:
On 23/08/2024 12:03, Stefan Ram wrote:
What gnarly waves are you missing out on in efficient and
idiomatic C programming by thinking, "I'll use my container
library and write C like it's some Silicon Valley startup code!"
So, what have you done with the real Stefan Ram?
It looks like real Stephan Ram hatched out of old restrictive eggshell
few months ago. BTW, in order to compare his writing style of old with
the new one, I
tried to look for his posts on Google Groups. It turned out that I can
only see citations. Posts themselves are not archived. Mysterious.
On Fri, 23 Aug 2024 12:18:38 +0100
Bart <bc@freeuk.com> wrote:
So, what have you done with the real Stefan Ram?
It looks like real Stephan Ram hatched out of old restrictive eggshell
few months ago.
BTW, in order to compare his writing style of old with the new one, I
tried to look for his posts on Google Groups. It turned out that I can
only see citations. Posts themselves are not archived. Mysterious.
There's an option you can choose to prevent your messages from being
saved; I'm not sure how it is set, and I don't remember whether it was
Google Groups specific or applied to all usenet servers. I do know,
however, that Stephan Ram routinely used that option, which makes
annoying gaps in the archived conversations.
On Thu, 2024-08-22 at 08:18 -0300, Thiago Adams wrote:
<snip/>
C++ made the usage of 'this->' optional when calling member functions.
As a result, when C++ programmers encounter 'i' in the middle of a
function, they might not know where it comes from.
If 'this->' were not optional, 'this->i' would clarify that.
To avoid confusion, many C++ programmers use prefixes like 'm_' that
can't be ignored.
Since many C programmers also work in C++, this pattern can sometimes
influence C code as well.
Although I think this is stupid thing to do when writing C, the same convention also exits in Python PEP-8 [1]
_single_leading_underscore: weak “internal use” indicator. E.g. from
M import * does not import objects whose names start with an
underscore.
[1]: https://peps.python.org/pep-0008/#descriptive-naming-styles
Annada Behera wrote:
If 'this->' were not optional, 'this->i' would clarify that.
To avoid confusion, many C++ programmers use prefixes like 'm_' that
can't be ignored.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 546 |
Nodes: | 16 (0 / 16) |
Uptime: | 168:22:02 |
Calls: | 10,385 |
Calls today: | 2 |
Files: | 14,057 |
Messages: | 6,416,545 |