Live data from Hacker News

Understanding Memory Management, Part 1: C

educatedguesswork.org

21–30 of 95 posts

Re: Understanding Memory Management, Part 1: C

#21

This isn't proper usage of realloc: lines = realloc(lines, (num_lines + 1) * sizeof(char *)); In case it cannot service the reallocation and returns NULL, it will overwrite "lines" with NULL, but the memory that "lines" referred to is still there and needs to be either freed or used. The proper way to call it would be: tmp = realloc(lines, (num_lines + 1) * sizeof(char *)); if (tmp == NULL) { free(lines); lines = NUL…

It is even flagged as such on Visual Studio analyser.

Re: Understanding Memory Management, Part 1: C

#22
post #17

Memory arenas should be taught to all programmers and become the default method of memory management.

They're a great fit in many situations but certainly not all. Why not teach programmers a variety of allocation strategies and how to recognize when each might be a good fit?

I initially read your username as boehm, and I was like wow, ok, this is a guy who knows his memory. :)

What situations would an arena allocator prove problematic or non-optimal, aside from the many allocations/deallocations scenario?

This is an area I'm very interested in, so any info would be appreciated.

Re: Understanding Memory Management, Part 1: C

#24
post #16
post #13

Earlier quoted context omitted.

Actually, no. You've just committed one of the cardinal sins of the *alloc()'s, which is: NULL is an acceptable return, so errno != 0 is the only way to tell if things have gone awry. The proper use of realloc is to check errno always ... because in fact it can return NULL in a case which is not considered an error: lines is not NULL but requested size is zero. This is not considered an error case. So, in your fix, p…

From `malloc(3)`: Nonportable behavior The behavior of these functions when the requested size is zero is glibc specific; other implementations may return NULL without setting errno, and portable POSIX programs should tolerate such behavior. See realloc(3p). POSIX requires memory allocators to set errno upon failure. However, the C standard does not require this, and applications portable to non-POSIX platforms shoul…

As someone writing C for POSIX and embedded environments, this clarification is a super helpful.

Re: Understanding Memory Management, Part 1: C

#25
post #12

Avoid as much as you can the C standard lib allocator, go directly to mmap system call with your own allocator if you know you won't use CPU without a MMU. If you write a library, let the user code install its own allocator.

"malloc" is a weakly-bound symbol that can be overridden, on every system I've used. I don't know if some standard defines it to be weak. Anyway the point is that malloc is not necessarily a call to the C standard library function. It can be anything.

Re: Understanding Memory Management, Part 1: C

#26

This isn't proper usage of realloc: lines = realloc(lines, (num_lines + 1) * sizeof(char *)); In case it cannot service the reallocation and returns NULL, it will overwrite "lines" with NULL, but the memory that "lines" referred to is still there and needs to be either freed or used. The proper way to call it would be: tmp = realloc(lines, (num_lines + 1) * sizeof(char *)); if (tmp == NULL) { free(lines); lines = NUL…

I feel like this comment is misleading because it gives the impression that the code in the article is wrong or unsafe, whereas I think it's actually fine? In the article, in the case when `tmp == NULL` (in your notation) the author aborts the program. This means there's no memory leak or unsafety. I agree that one can do better of course.

Re: Understanding Memory Management, Part 1: C

#27

This isn't proper usage of realloc: lines = realloc(lines, (num_lines + 1) * sizeof(char *)); In case it cannot service the reallocation and returns NULL, it will overwrite "lines" with NULL, but the memory that "lines" referred to is still there and needs to be either freed or used. The proper way to call it would be: tmp = realloc(lines, (num_lines + 1) * sizeof(char *)); if (tmp == NULL) { free(lines); lines = NUL…

There's another bug, related to performance - this involves a quadratic amount of memory copying unless your environment can arrange for zero-copy.

Re: Understanding Memory Management, Part 1: C

#28
post #17

Earlier quoted context omitted.

They're a great fit in many situations but certainly not all. Why not teach programmers a variety of allocation strategies and how to recognize when each might be a good fit?

I initially read your username as boehm, and I was like wow, ok, this is a guy who knows his memory. :) What situations would an arena allocator prove problematic or non-optimal, aside from the many allocations/deallocations scenario? This is an area I'm very interested in, so any info would be appreciated.

In general, everything allocated within an arena has its lifetime tied to that arena. In lots of situations this is a fine or even desirable property (e.g., a single request context in a server application), but can be a tough restriction to work with in situations where you need fine-grained deallocations and possibly want to reuse freed space. The lifetime property can also be a pain to work with in multithreaded scenarios, where you might have multiple threads needing to access data stored in a single arena. Another situation that comes to mind is large long-lived allocations where you might want to have some manual defragmentation in place for performance reasons.

Re: Understanding Memory Management, Part 1: C

#29
post #25
post #12

Avoid as much as you can the C standard lib allocator, go directly to mmap system call with your own allocator if you know you won't use CPU without a MMU. If you write a library, let the user code install its own allocator.

"malloc" is a weakly-bound symbol that can be overridden, on every system I've used. I don't know if some standard defines it to be weak. Anyway the point is that malloc is not necessarily a call to the C standard library function. It can be anything.

"weakly-bound symbol" implies your a using a complex runtime library/binary format (like ELF).

A portable and clean design for a library is to allow to override the internal allocator via the API (often part of the init function call).

Look at vulkan3D which does many things right and doing this very part right. On the other side, you have some parts of the ALSA lib API which still requires to use the C lib free (may be obsolete though).

Re: Understanding Memory Management, Part 1: C

#30
post #29
post #25

Earlier quoted context omitted.

"malloc" is a weakly-bound symbol that can be overridden, on every system I've used. I don't know if some standard defines it to be weak. Anyway the point is that malloc is not necessarily a call to the C standard library function. It can be anything.

"weakly-bound symbol" implies your a using a complex runtime library/binary format (like ELF). A portable and clean design for a library is to allow to override the internal allocator via the API (often part of the init function call). Look at vulkan3D which does many things right and doing this very part right. On the other side, you have some parts of the ALSA lib API which still requires to use the C lib free (may…

No, it doesn't mean that, because malloc can be replaced at build-time as well. But I agree that interfaces should avoid doing their own allocations and should let the caller dictate it.
Post reply on HN