Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Post History

50%
+2 −2
Q&A How to properly use malloc?

There are several things to consider when calling the malloc(3) family of functions: nelem * sizeof(elem) or sizeof(elem) * nelem? Use the type or the pointer name in sizeof()? To cast or not ...

posted 1y ago by alx‭  ·  edited 1y ago by alx‭

Answer
#10: Post edited by user avatar alx‭ · 2023-04-12T00:53:13Z (about 1 year ago)
  • There are several things to consider when calling the _malloc(3)_ family of functions:
  • - `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • - Use the type or the pointer name in `sizeof()`?
  • - To cast or not to cast?
  • TL;DR:
  • Use a simple and readable interface, and let it handle the safety for you. Then, write such an interface.
  • ```c
  • foo_t *p;
  • p = MALLOC(nelem, foo_t);
  • ```
  • Let's answer the questions one by one.
  • ---
  • ### `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • None of the alternatives is good.
  • Use functions that take separate arguments:
  • - `calloc(3)` (ISO C)
  • - `reallocarray(3)` (several Unix systems)
  • - `recallocarray(3)` (several Unix systems)
  • I suggest writing your own _mallocarray()_ and _reallocarrayf()_ as wrappers around these. _reallocarrayf()_ is more complex (read about _reallocf(3)_), but _mallocarray()_ can be trivially implemented:
  • ```c
  • #define mallocarray(nmemb, size) reallocarray(NULL, nmemb, size)
  • ```
  • As a rule, I _always_ use array allocation functions, even if I only want 1 element:
  • ```c
  • foo_t *p;
  • // p = MALLOC(1, foo_t); // which expands to:
  • p = (foo_t *) mallocarray(1, sizeof(foo_t));
  • ```
  • This has several benefits:
  • - It clearly shows the number of elements I want. If it's 1, or if it's 42.
  • An exception is when allocating a structure with a flexible array member. In such case, you really need to call _malloc(3)_ with the precise size you want:
  • ```c
  • struct foo {
  • int a;
  • bar_t b[];
  • };
  • struct foo *p;
  • p = (struct foo *) malloc(sizeof(struct foo) + sizeof(bar_t) * n);
  • ```
  • - The multiplication is performed inside the function, inside a check to prevent overflow.
  • However, as a general rule, when you multiply numbers, put first the value with the widest type, to avoid overflowing intermediate operations (read about precedence in operators).
  • ```c
  • int a, b;
  • size_t c, d;
  • ...
  • d = a * b * c; // might overflow `a * b` easily
  • d = c * a * b; // less likely
  • ```
  • ---
  • ### Use the type or the pointer name in _sizeof()_?
  • None of the alternatives is good.
  • If you use the type, then if you change the type of the pointer might introduce silent bugs in _malloc(3)_ calls, since there's no way that the compiler knows if your doing the right thing.
  • If you use the name, then you reduce ability to search in the code. Code is more often read (and searched) than modified. It's quite useful to be able to search through a code base for all allocations of a given type with something like the following.
  • ```sh
  • grep -rni 'alloc.*\bfoo_t)' src
  • ```
  • The solution comes thanks to the next question, which is about casting. As a starter, I'll say that in this case readability is preferable to safety; we'll try to make it safe somehow... continue reading.
  • ---
  • ### To cast or not to cast? That is the question.
  • The unsurprising answer, again, is that none of the alternatives is good.
  • Casting, in general, can disable many warnings, and is a dreaded thing that should be used very carefully. However, that doesn't apply to _malloc(3)_, since it (by returning `void *`) implicitly converts to _any_ pointer type, so we can't do more damage by forcing a conversion.
  • Casting also had issues regarding implicit functions, but those are gone for good (since C99), so this is a non-issue. If you lived in a cave for the last `$year - 1999` years, please get out and see the light.
  • Casts still have issues, which is why they're not ideal:
  • - Clutters the code, considerably reducing readability.
  • - They aren't DRY.
  • So let's not write the cast (which is not the same as don't cast).
  • Casting the result of _malloc(3)_ is good because:
  • - It couples the call with the type of the pointer. Since the cast converts the `void *` to a non-`void` pointer, it no longer converts to anything implicitly. This means that if the type of the pointer ever changes, _malloc(3)_ calls assigned to that pointer will no longer compile, and we will be able to fix any compilation errors.
  • So, the solution is to write the cast inside a macro, which uses the same information that we will need for _sizeof()_, thus avoiding repeating ourselves, and also avoiding readability issues.
  • ```c
  • #define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
  • ```
  • which is to be used as this:
  • ```c
  • foo_t *p;
  • p = MALLOC(42, foo_t); // 42 elements of type foo_t.
  • ```
  • It's readable, it's concise, it's easily searchable, and it's safe.
  • There are several things to consider when calling the _malloc(3)_ family of functions:
  • - `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • - Use the type or the pointer name in `sizeof()`?
  • - To cast or not to cast?
  • TL;DR:
  • Use a simple and readable interface, and let it handle the safety for you. Of course, you need to write such an interface, wrapping the standard C library functions.
  • ```c
  • foo_t *p;
  • p = MALLOC(nelem, foo_t);
  • ```
  • Let's answer the questions one by one.
  • ---
  • ### `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • None of the alternatives is good.
  • Use functions that take separate arguments:
  • - `calloc(3)` (ISO C)
  • - `reallocarray(3)` (several Unix systems)
  • - `recallocarray(3)` (several Unix systems)
  • I suggest writing your own _mallocarray()_ and _reallocarrayf()_ as wrappers around these. _reallocarrayf()_ is more complex (read about _reallocf(3)_), but _mallocarray()_ can be trivially implemented:
  • ```c
  • #define mallocarray(nmemb, size) reallocarray(NULL, nmemb, size)
  • ```
  • As a rule, I _always_ use array allocation functions, even if I only want 1 element:
  • ```c
  • foo_t *p;
  • // p = MALLOC(1, foo_t); // which expands to:
  • p = (foo_t *) mallocarray(1, sizeof(foo_t));
  • ```
  • This has several benefits:
  • - It clearly shows the number of elements I want. If it's 1, or if it's 42.
  • An exception is when allocating a structure with a flexible array member. In such case, you really need to call _malloc(3)_ with the precise size you want:
  • ```c
  • struct foo {
  • int a;
  • bar_t b[];
  • };
  • struct foo *p;
  • p = (struct foo *) malloc(sizeof(struct foo) + sizeof(bar_t) * n);
  • ```
  • - The multiplication is performed inside the function, inside a check to prevent overflow.
  • However, as a general rule, when you multiply numbers, put first the value with the widest type, to avoid overflowing intermediate operations (read about precedence in operators).
  • ```c
  • int a, b;
  • size_t c, d;
  • ...
  • d = a * b * c; // might overflow `a * b` easily
  • d = c * a * b; // less likely
  • ```
  • ---
  • ### Use the type or the pointer name in _sizeof()_?
  • None of the alternatives is good.
  • If you use the type, then if you change the type of the pointer might introduce silent bugs in _malloc(3)_ calls, since there's no way that the compiler knows if your doing the right thing.
  • If you use the name, then you reduce ability to search in the code. Code is more often read (and searched) than modified. It's quite useful to be able to search through a code base for all allocations of a given type with something like the following.
  • ```sh
  • grep -rni 'alloc.*\bfoo_t)' src
  • ```
  • The solution comes thanks to the next question, which is about casting. As a starter, I'll say that in this case readability is preferable to safety; we'll try to make it safe somehow... continue reading.
  • ---
  • ### To cast or not to cast? That is the question.
  • The unsurprising answer, again, is that none of the alternatives is good.
  • Casting, in general, can disable many warnings, and is a dreaded thing that should be used very carefully. However, that doesn't apply to _malloc(3)_, since it (by returning `void *`) implicitly converts to _any_ pointer type, so we can't do more damage by forcing a conversion.
  • Casting also had issues regarding implicit functions, but those are gone for good (since C99), so this is a non-issue. If you lived in a cave for the last `$year - 1999` years, please get out and see the light.
  • Casts still have issues, which is why they're not ideal:
  • - Clutters the code, considerably reducing readability.
  • - They aren't DRY.
  • So let's not write the cast (which is not the same as don't cast).
  • Casting the result of _malloc(3)_ is good because:
  • - It couples the call with the type of the pointer. Since the cast converts the `void *` to a non-`void` pointer, it no longer converts to anything implicitly. This means that if the type of the pointer ever changes, _malloc(3)_ calls assigned to that pointer will no longer compile, and we will be able to fix any compilation errors.
  • So, the solution is to write the cast inside a macro, which uses the same information that we will need for _sizeof()_, thus avoiding repeating ourselves, and also avoiding readability issues.
  • ```c
  • #define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
  • ```
  • which is to be used as this:
  • ```c
  • foo_t *p;
  • p = MALLOC(42, foo_t); // 42 elements of type foo_t.
  • ```
  • It's readable, it's concise, it's easily searchable, and it's safe.
#9: Post edited by user avatar alx‭ · 2023-04-12T00:52:31Z (about 1 year ago)
  • There are several things to consider when calling the _malloc(3)_ family of functions:
  • - `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • - Use the type or the pointer name in `sizeof()`?
  • - To cast or not to cast?
  • TL;DR:
  • Use a simple and readable interface, and let it handle the safety for you.
  • ```c
  • foo_t *p;
  • p = MALLOC(nelem, foo_t);
  • ```
  • Let's answer the questions one by one.
  • ---
  • ### `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • None of the alternatives is good.
  • Use functions that take separate arguments:
  • - `calloc(3)` (ISO C)
  • - `reallocarray(3)` (several Unix systems)
  • - `recallocarray(3)` (several Unix systems)
  • I suggest writing your own _mallocarray()_ and _reallocarrayf()_ as wrappers around these. _reallocarrayf()_ is more complex (read about _reallocf(3)_), but _mallocarray()_ can be trivially implemented:
  • ```c
  • #define mallocarray(nmemb, size) reallocarray(NULL, nmemb, size)
  • ```
  • As a rule, I _always_ use array allocation functions, even if I only want 1 element:
  • ```c
  • foo_t *p;
  • // p = MALLOC(1, foo_t); // which expands to:
  • p = (foo_t *) mallocarray(1, sizeof(foo_t));
  • ```
  • This has several benefits:
  • - It clearly shows the number of elements I want. If it's 1, or if it's 42.
  • An exception is when allocating a structure with a flexible array member. In such case, you really need to call _malloc(3)_ with the precise size you want:
  • ```c
  • struct foo {
  • int a;
  • bar_t b[];
  • };
  • struct foo *p;
  • p = (struct foo *) malloc(sizeof(struct foo) + sizeof(bar_t) * n);
  • ```
  • - The multiplication is performed inside the function, inside a check to prevent overflow.
  • However, as a general rule, when you multiply numbers, put first the value with the widest type, to avoid overflowing intermediate operations (read about precedence in operators).
  • ```c
  • int a, b;
  • size_t c, d;
  • ...
  • d = a * b * c; // might overflow `a * b` easily
  • d = c * a * b; // less likely
  • ```
  • ---
  • ### Use the type or the pointer name in _sizeof()_?
  • None of the alternatives is good.
  • If you use the type, then if you change the type of the pointer might introduce silent bugs in _malloc(3)_ calls, since there's no way that the compiler knows if your doing the right thing.
  • If you use the name, then you reduce ability to search in the code. Code is more often read (and searched) than modified. It's quite useful to be able to search through a code base for all allocations of a given type with something like the following.
  • ```sh
  • grep -rni 'alloc.*\bfoo_t)' src
  • ```
  • The solution comes thanks to the next question, which is about casting. As a starter, I'll say that in this case readability is preferable to safety; we'll try to make it safe somehow... continue reading.
  • ---
  • ### To cast or not to cast? That is the question.
  • The unsurprising answer, again, is that none of the alternatives is good.
  • Casting, in general, can disable many warnings, and is a dreaded thing that should be used very carefully. However, that doesn't apply to _malloc(3)_, since it (by returning `void *`) implicitly converts to _any_ pointer type, so we can't do more damage by forcing a conversion.
  • Casting also had issues regarding implicit functions, but those are gone for good (since C99), so this is a non-issue. If you lived in a cave for the last `$year - 1999` years, please get out and see the light.
  • Casts still have issues, which is why they're not ideal:
  • - Clutters the code, considerably reducing readability.
  • - They aren't DRY.
  • So let's not write the cast (which is not the same as don't cast).
  • Casting the result of _malloc(3)_ is good because:
  • - It couples the call with the type of the pointer. Since the cast converts the `void *` to a non-`void` pointer, it no longer converts to anything implicitly. This means that if the type of the pointer ever changes, _malloc(3)_ calls assigned to that pointer will no longer compile, and we will be able to fix any compilation errors.
  • So, the solution is to write the cast inside a macro, which uses the same information that we will need for _sizeof()_, thus avoiding repeating ourselves, and also avoiding readability issues.
  • ```c
  • #define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
  • ```
  • which is to be used as this:
  • ```c
  • foo_t *p;
  • p = MALLOC(42, foo_t); // 42 elements of type foo_t.
  • ```
  • It's readable, it's concise, it's easily searchable, and it's safe.
  • There are several things to consider when calling the _malloc(3)_ family of functions:
  • - `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • - Use the type or the pointer name in `sizeof()`?
  • - To cast or not to cast?
  • TL;DR:
  • Use a simple and readable interface, and let it handle the safety for you. Then, write such an interface.
  • ```c
  • foo_t *p;
  • p = MALLOC(nelem, foo_t);
  • ```
  • Let's answer the questions one by one.
  • ---
  • ### `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • None of the alternatives is good.
  • Use functions that take separate arguments:
  • - `calloc(3)` (ISO C)
  • - `reallocarray(3)` (several Unix systems)
  • - `recallocarray(3)` (several Unix systems)
  • I suggest writing your own _mallocarray()_ and _reallocarrayf()_ as wrappers around these. _reallocarrayf()_ is more complex (read about _reallocf(3)_), but _mallocarray()_ can be trivially implemented:
  • ```c
  • #define mallocarray(nmemb, size) reallocarray(NULL, nmemb, size)
  • ```
  • As a rule, I _always_ use array allocation functions, even if I only want 1 element:
  • ```c
  • foo_t *p;
  • // p = MALLOC(1, foo_t); // which expands to:
  • p = (foo_t *) mallocarray(1, sizeof(foo_t));
  • ```
  • This has several benefits:
  • - It clearly shows the number of elements I want. If it's 1, or if it's 42.
  • An exception is when allocating a structure with a flexible array member. In such case, you really need to call _malloc(3)_ with the precise size you want:
  • ```c
  • struct foo {
  • int a;
  • bar_t b[];
  • };
  • struct foo *p;
  • p = (struct foo *) malloc(sizeof(struct foo) + sizeof(bar_t) * n);
  • ```
  • - The multiplication is performed inside the function, inside a check to prevent overflow.
  • However, as a general rule, when you multiply numbers, put first the value with the widest type, to avoid overflowing intermediate operations (read about precedence in operators).
  • ```c
  • int a, b;
  • size_t c, d;
  • ...
  • d = a * b * c; // might overflow `a * b` easily
  • d = c * a * b; // less likely
  • ```
  • ---
  • ### Use the type or the pointer name in _sizeof()_?
  • None of the alternatives is good.
  • If you use the type, then if you change the type of the pointer might introduce silent bugs in _malloc(3)_ calls, since there's no way that the compiler knows if your doing the right thing.
  • If you use the name, then you reduce ability to search in the code. Code is more often read (and searched) than modified. It's quite useful to be able to search through a code base for all allocations of a given type with something like the following.
  • ```sh
  • grep -rni 'alloc.*\bfoo_t)' src
  • ```
  • The solution comes thanks to the next question, which is about casting. As a starter, I'll say that in this case readability is preferable to safety; we'll try to make it safe somehow... continue reading.
  • ---
  • ### To cast or not to cast? That is the question.
  • The unsurprising answer, again, is that none of the alternatives is good.
  • Casting, in general, can disable many warnings, and is a dreaded thing that should be used very carefully. However, that doesn't apply to _malloc(3)_, since it (by returning `void *`) implicitly converts to _any_ pointer type, so we can't do more damage by forcing a conversion.
  • Casting also had issues regarding implicit functions, but those are gone for good (since C99), so this is a non-issue. If you lived in a cave for the last `$year - 1999` years, please get out and see the light.
  • Casts still have issues, which is why they're not ideal:
  • - Clutters the code, considerably reducing readability.
  • - They aren't DRY.
  • So let's not write the cast (which is not the same as don't cast).
  • Casting the result of _malloc(3)_ is good because:
  • - It couples the call with the type of the pointer. Since the cast converts the `void *` to a non-`void` pointer, it no longer converts to anything implicitly. This means that if the type of the pointer ever changes, _malloc(3)_ calls assigned to that pointer will no longer compile, and we will be able to fix any compilation errors.
  • So, the solution is to write the cast inside a macro, which uses the same information that we will need for _sizeof()_, thus avoiding repeating ourselves, and also avoiding readability issues.
  • ```c
  • #define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
  • ```
  • which is to be used as this:
  • ```c
  • foo_t *p;
  • p = MALLOC(42, foo_t); // 42 elements of type foo_t.
  • ```
  • It's readable, it's concise, it's easily searchable, and it's safe.
#8: Post edited by user avatar alx‭ · 2023-04-04T14:21:56Z (about 1 year ago)
  • There are several things to consider when calling the _malloc(3)_ family of functions:
  • - `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • - Use the type or the pointer name in `sizeof()`?
  • - To cast or not to cast?
  • TL;DR:
  • Use a simple and readable interface, and let it handle the safety for you.
  • ```c
  • foo_t *p;
  • p = MALLOC(nelem, foo_t);
  • ```
  • Let's answer the questions one by one.
  • ---
  • ### `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • None of the alternatives is good.
  • Use functions that take separate arguments:
  • - `calloc(3)` (ISO C)
  • - `reallocarray(3)` (several Unix systems)
  • - `recallocarray(3)` (several Unix systems)
  • I suggest writing your own _mallocarray()_ and _reallocarrayf()_ as wrappers around these. _reallocarrayf()_ is more complex (read about _reallocf(3)_), but _mallocarray()_ can be trivially implemented:
  • ```c
  • #define mallocarray(nmemb, size) reallocarray(NULL, nmemb, size)
  • ```
  • As a rule, I _always_ use array allocation functions, even if I only want 1 element:
  • ```c
  • foo_t *p;
  • // p = MALLOC(1, foo_t); // which expands to:
  • p = (foo_t *) mallocarray(1, sizeof(foo_t));
  • ```
  • This has several benefits:
  • - It clearly shows the number of elements I want. If it's 1, or if it's 42.
  • An exception is when allocating a structure with a flexible array member. In such case, you really need to call _malloc(3)_ with the precise size you want:
  • ```c
  • struct foo {
  • int a;
  • bar_t b[];
  • };
  • struct foo *p;
  • p = (struct foo *) malloc(sizeof(struct foo) + sizeof(bar_t) * n);
  • ```
  • - The multiplication is performed inside the function, inside a check to prevent overflow.
  • However, as a general rule, when you multiply numbers, put first the value with the widest type, to avoid overflowing intermediate operations (read about precedence in operators).
  • ```c
  • int a, b;
  • size_t c, d;
  • ...
  • d = a * b * c; // might overflow `a * b` easily
  • d = c * a * b; // less likely
  • ```
  • ---
  • ### Use the type or the pointer name in _sizeof()_?
  • None of the alternatives is good.
  • If you use the type, then if you change the type of the pointer might introduce silent bugs in _malloc(3)_ calls, since there's no way that the compiler knows if your doing the right thing.
  • If you use the name, then you reduce ability to search in the code. Code is more often read (and searched) than modified. It's quite useful to be able to search through a code base for all allocations of a given type with something like the following.
  • ```sh
  • grep -rni 'alloc.*\bfoo_t)' src
  • ```
  • The solution comes thanks to the next question, which is about casting. As a starter, I'll say that in this case readability is preferable to safety; we'll try to make it safe somehow... continue reading.
  • ---
  • ### To cast or not to cast? That is the question.
  • The unsurprising answer, again, is that none of the alternatives is good.
  • Casting, in general, can disable many warnings, and is a dreaded thing that should be used very carefully. However, that doesn't apply to _malloc(3)_, since it (by returning `void *`) implicitly converts to _any_ pointer type, so we can't do more damage by forcing a conversion.
  • Casting also had issues regarding implicit functions, but those are gone for good (since C99), so this is a non-issue. If you lived in a cave for the last 24 years, please get out and see the light.
  • Casts still have issues, which is why they're not ideal:
  • - Clutters the code, considerably reducing readability.
  • - They aren't DRY.
  • So let's not write the cast (which is not the same as don't cast).
  • Casting the result of _malloc(3)_ is good because:
  • - It couples the call with the type of the pointer. Since the cast converts the `void *` to a non-`void` pointer, it no longer converts to anything implicitly. This means that if the type of the pointer ever changes, _malloc(3)_ calls assigned to that pointer will no longer compile, and we will be able to fix any compilation errors.
  • So, the solution is to write the cast inside a macro, which uses the same information that we will need for _sizeof()_, thus avoiding repeating ourselves, and also avoiding readability issues.
  • ```c
  • #define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
  • ```
  • which is to be used as this:
  • ```c
  • foo_t *p;
  • p = MALLOC(42, foo_t); // 42 elements of type foo_t.
  • ```
  • It's readable, it's concise, it's easily searchable, and it's safe.
  • There are several things to consider when calling the _malloc(3)_ family of functions:
  • - `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • - Use the type or the pointer name in `sizeof()`?
  • - To cast or not to cast?
  • TL;DR:
  • Use a simple and readable interface, and let it handle the safety for you.
  • ```c
  • foo_t *p;
  • p = MALLOC(nelem, foo_t);
  • ```
  • Let's answer the questions one by one.
  • ---
  • ### `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • None of the alternatives is good.
  • Use functions that take separate arguments:
  • - `calloc(3)` (ISO C)
  • - `reallocarray(3)` (several Unix systems)
  • - `recallocarray(3)` (several Unix systems)
  • I suggest writing your own _mallocarray()_ and _reallocarrayf()_ as wrappers around these. _reallocarrayf()_ is more complex (read about _reallocf(3)_), but _mallocarray()_ can be trivially implemented:
  • ```c
  • #define mallocarray(nmemb, size) reallocarray(NULL, nmemb, size)
  • ```
  • As a rule, I _always_ use array allocation functions, even if I only want 1 element:
  • ```c
  • foo_t *p;
  • // p = MALLOC(1, foo_t); // which expands to:
  • p = (foo_t *) mallocarray(1, sizeof(foo_t));
  • ```
  • This has several benefits:
  • - It clearly shows the number of elements I want. If it's 1, or if it's 42.
  • An exception is when allocating a structure with a flexible array member. In such case, you really need to call _malloc(3)_ with the precise size you want:
  • ```c
  • struct foo {
  • int a;
  • bar_t b[];
  • };
  • struct foo *p;
  • p = (struct foo *) malloc(sizeof(struct foo) + sizeof(bar_t) * n);
  • ```
  • - The multiplication is performed inside the function, inside a check to prevent overflow.
  • However, as a general rule, when you multiply numbers, put first the value with the widest type, to avoid overflowing intermediate operations (read about precedence in operators).
  • ```c
  • int a, b;
  • size_t c, d;
  • ...
  • d = a * b * c; // might overflow `a * b` easily
  • d = c * a * b; // less likely
  • ```
  • ---
  • ### Use the type or the pointer name in _sizeof()_?
  • None of the alternatives is good.
  • If you use the type, then if you change the type of the pointer might introduce silent bugs in _malloc(3)_ calls, since there's no way that the compiler knows if your doing the right thing.
  • If you use the name, then you reduce ability to search in the code. Code is more often read (and searched) than modified. It's quite useful to be able to search through a code base for all allocations of a given type with something like the following.
  • ```sh
  • grep -rni 'alloc.*\bfoo_t)' src
  • ```
  • The solution comes thanks to the next question, which is about casting. As a starter, I'll say that in this case readability is preferable to safety; we'll try to make it safe somehow... continue reading.
  • ---
  • ### To cast or not to cast? That is the question.
  • The unsurprising answer, again, is that none of the alternatives is good.
  • Casting, in general, can disable many warnings, and is a dreaded thing that should be used very carefully. However, that doesn't apply to _malloc(3)_, since it (by returning `void *`) implicitly converts to _any_ pointer type, so we can't do more damage by forcing a conversion.
  • Casting also had issues regarding implicit functions, but those are gone for good (since C99), so this is a non-issue. If you lived in a cave for the last `$year - 1999` years, please get out and see the light.
  • Casts still have issues, which is why they're not ideal:
  • - Clutters the code, considerably reducing readability.
  • - They aren't DRY.
  • So let's not write the cast (which is not the same as don't cast).
  • Casting the result of _malloc(3)_ is good because:
  • - It couples the call with the type of the pointer. Since the cast converts the `void *` to a non-`void` pointer, it no longer converts to anything implicitly. This means that if the type of the pointer ever changes, _malloc(3)_ calls assigned to that pointer will no longer compile, and we will be able to fix any compilation errors.
  • So, the solution is to write the cast inside a macro, which uses the same information that we will need for _sizeof()_, thus avoiding repeating ourselves, and also avoiding readability issues.
  • ```c
  • #define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
  • ```
  • which is to be used as this:
  • ```c
  • foo_t *p;
  • p = MALLOC(42, foo_t); // 42 elements of type foo_t.
  • ```
  • It's readable, it's concise, it's easily searchable, and it's safe.
#7: Post edited by user avatar alx‭ · 2023-04-04T14:17:11Z (about 1 year ago)
  • There are several things to consider when calling the _malloc(3)_ family of functions:
  • - `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • - Use the type or the pointer name in `sizeof()`?
  • - To cast or not to cast?
  • TL;DR:
  • Use a simple and readable interface, and let it handle the safety for you.
  • ```c
  • foo_t *p;
  • p = MALLOC(nelem, foo_t);
  • ```
  • Let's answer the questions one by one.
  • ---
  • ### `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • None of the alternatives is good.
  • Use functions that take separate arguments:
  • - `calloc(3)` (ISO C)
  • - `reallocarray(3)` (several Unix systems)
  • I suggest writing your own _mallocarray()_ and _reallocarrayf()_ as wrappers around these. _reallocarrayf()_ is more complex (read about _reallocf(3)_), but _mallocarray()_ can be trivially implemented:
  • ```c
  • #define mallocarray(nmemb, size) reallocarray(NULL, nmemb, size)
  • ```
  • As a rule, I _always_ use array allocation functions, even if I only want 1 element:
  • ```c
  • foo_t *p;
  • // p = MALLOC(1, foo_t); // which expands to:
  • p = (foo_t *) mallocarray(1, sizeof(foo_t));
  • ```
  • This has several benefits:
  • - It clearly shows the number of elements I want. If it's 1, or if it's 42.
  • An exception is when allocating a structure with a flexible array member. In such case, you really need to call _malloc(3)_ with the precise size you want:
  • ```c
  • struct foo {
  • int a;
  • bar_t b[];
  • };
  • struct foo *p;
  • p = (struct foo *) malloc(sizeof(struct foo) + sizeof(bar_t) * n);
  • ```
  • - The multiplication is performed inside the function, inside a check to prevent overflow.
  • However, as a general rule, when you multiply numbers, put first the value with the widest type, to avoid overflowing intermediate operations (read about precedence in operators).
  • ```c
  • int a, b;
  • size_t c, d;
  • ...
  • d = a * b * c; // might overflow `a * b` easily
  • d = c * a * b; // less likely
  • ```
  • ---
  • ### Use the type or the pointer name in _sizeof()_?
  • None of the alternatives is good.
  • If you use the type, then if you change the type of the pointer might introduce silent bugs in _malloc(3)_ calls, since there's no way that the compiler knows if your doing the right thing.
  • If you use the name, then you reduce ability to search in the code. Code is more often read (and searched) than modified. It's quite useful to be able to search through a code base for all allocations of a given type with something like the following.
  • ```sh
  • grep -rni 'alloc.*\bfoo_t)' src
  • ```
  • The solution comes thanks to the next question, which is about casting. As a starter, I'll say that in this case readability is preferable to safety; we'll try to make it safe somehow... continue reading.
  • ---
  • ### To cast or not to cast? That is the question.
  • The unsurprising answer, again, is that none of the alternatives is good.
  • Casting, in general, can disable many warnings, and is a dreaded thing that should be used very carefully. However, that doesn't apply to _malloc(3)_, since it (by returning `void *`) implicitly converts to _any_ pointer type, so we can't do more damage by forcing a conversion.
  • Casting also had issues regarding implicit functions, but those are gone for good (since C99), so this is a non-issue. If you lived in a cave for the last 24 years, please get out and see the light.
  • Casts still have issues, which is why they're not ideal:
  • - Clutters the code, considerably reducing readability.
  • - They aren't DRY.
  • So let's not write the cast (which is not the same as don't cast).
  • Casting the result of _malloc(3)_ is good because:
  • - It couples the call with the type of the pointer. Since the cast converts the `void *` to a non-`void` pointer, it no longer converts to anything implicitly. This means that if the type of the pointer ever changes, _malloc(3)_ calls assigned to that pointer will no longer compile, and we will be able to fix any compilation errors.
  • So, the solution is to write the cast inside a macro, which uses the same information that we will need for _sizeof()_, thus avoiding repeating ourselves, and also avoiding readability issues.
  • ```c
  • #define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
  • ```
  • which is to be used as this:
  • ```c
  • foo_t *p;
  • p = MALLOC(42, foo_t); // 42 elements of type foo_t.
  • ```
  • It's readable, it's concise, it's easily searchable, and it's safe.
  • There are several things to consider when calling the _malloc(3)_ family of functions:
  • - `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • - Use the type or the pointer name in `sizeof()`?
  • - To cast or not to cast?
  • TL;DR:
  • Use a simple and readable interface, and let it handle the safety for you.
  • ```c
  • foo_t *p;
  • p = MALLOC(nelem, foo_t);
  • ```
  • Let's answer the questions one by one.
  • ---
  • ### `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • None of the alternatives is good.
  • Use functions that take separate arguments:
  • - `calloc(3)` (ISO C)
  • - `reallocarray(3)` (several Unix systems)
  • - `recallocarray(3)` (several Unix systems)
  • I suggest writing your own _mallocarray()_ and _reallocarrayf()_ as wrappers around these. _reallocarrayf()_ is more complex (read about _reallocf(3)_), but _mallocarray()_ can be trivially implemented:
  • ```c
  • #define mallocarray(nmemb, size) reallocarray(NULL, nmemb, size)
  • ```
  • As a rule, I _always_ use array allocation functions, even if I only want 1 element:
  • ```c
  • foo_t *p;
  • // p = MALLOC(1, foo_t); // which expands to:
  • p = (foo_t *) mallocarray(1, sizeof(foo_t));
  • ```
  • This has several benefits:
  • - It clearly shows the number of elements I want. If it's 1, or if it's 42.
  • An exception is when allocating a structure with a flexible array member. In such case, you really need to call _malloc(3)_ with the precise size you want:
  • ```c
  • struct foo {
  • int a;
  • bar_t b[];
  • };
  • struct foo *p;
  • p = (struct foo *) malloc(sizeof(struct foo) + sizeof(bar_t) * n);
  • ```
  • - The multiplication is performed inside the function, inside a check to prevent overflow.
  • However, as a general rule, when you multiply numbers, put first the value with the widest type, to avoid overflowing intermediate operations (read about precedence in operators).
  • ```c
  • int a, b;
  • size_t c, d;
  • ...
  • d = a * b * c; // might overflow `a * b` easily
  • d = c * a * b; // less likely
  • ```
  • ---
  • ### Use the type or the pointer name in _sizeof()_?
  • None of the alternatives is good.
  • If you use the type, then if you change the type of the pointer might introduce silent bugs in _malloc(3)_ calls, since there's no way that the compiler knows if your doing the right thing.
  • If you use the name, then you reduce ability to search in the code. Code is more often read (and searched) than modified. It's quite useful to be able to search through a code base for all allocations of a given type with something like the following.
  • ```sh
  • grep -rni 'alloc.*\bfoo_t)' src
  • ```
  • The solution comes thanks to the next question, which is about casting. As a starter, I'll say that in this case readability is preferable to safety; we'll try to make it safe somehow... continue reading.
  • ---
  • ### To cast or not to cast? That is the question.
  • The unsurprising answer, again, is that none of the alternatives is good.
  • Casting, in general, can disable many warnings, and is a dreaded thing that should be used very carefully. However, that doesn't apply to _malloc(3)_, since it (by returning `void *`) implicitly converts to _any_ pointer type, so we can't do more damage by forcing a conversion.
  • Casting also had issues regarding implicit functions, but those are gone for good (since C99), so this is a non-issue. If you lived in a cave for the last 24 years, please get out and see the light.
  • Casts still have issues, which is why they're not ideal:
  • - Clutters the code, considerably reducing readability.
  • - They aren't DRY.
  • So let's not write the cast (which is not the same as don't cast).
  • Casting the result of _malloc(3)_ is good because:
  • - It couples the call with the type of the pointer. Since the cast converts the `void *` to a non-`void` pointer, it no longer converts to anything implicitly. This means that if the type of the pointer ever changes, _malloc(3)_ calls assigned to that pointer will no longer compile, and we will be able to fix any compilation errors.
  • So, the solution is to write the cast inside a macro, which uses the same information that we will need for _sizeof()_, thus avoiding repeating ourselves, and also avoiding readability issues.
  • ```c
  • #define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
  • ```
  • which is to be used as this:
  • ```c
  • foo_t *p;
  • p = MALLOC(42, foo_t); // 42 elements of type foo_t.
  • ```
  • It's readable, it's concise, it's easily searchable, and it's safe.
#6: Post edited by user avatar alx‭ · 2023-04-04T12:54:40Z (about 1 year ago)
  • There are several things to consider when calling the _malloc(3)_ family of functions:
  • - `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • - Use the type or the pointer name in `sizeof()`?
  • - To cast or not to cast?
  • TL;DR:
  • Use a simple and readable interface, and let it handle the safety for you.
  • ```c
  • foo_t *p;
  • p = MALLOC(nelem, foo_t);
  • ```
  • Let's answer the questions one by one.
  • ---
  • ### `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • None of the alternatives is good.
  • Use functions that take separate arguments:
  • - `calloc(3)` (ISO C)
  • - `reallocarray(3)` (several Unix systems)
  • I suggest writing your own _mallocarray()_ and _reallocarrayf()_ as wrappers around these. _reallocarrayf()_ is more complex (read about _reallocf(3)_), but _mallocarray()_ can be trivially implemented:
  • ```c
  • #define mallocarray(nmemb, size) reallocarray(NULL, nmemb, size)
  • ```
  • As a rule, I _always_ use array allocation functions, even if I only want 1 element:
  • ```c
  • foo_t *p;
  • // p = MALLOC(1, foo_t); // which expands to:
  • p = (foo_t *) mallocarray(1, sizeof(foo_t));
  • ```
  • This has several benefits:
  • - It clearly shows the number of elements I want. If it's 1, or if it's 42.
  • An exception is when allocating a structure with a flexible array member. In such case, you really need to call _malloc(3)_ with the precise size you want:
  • ```c
  • struct foo {
  • int a;
  • bar_t b[];
  • };
  • struct foo *p;
  • p = (struct foo *) malloc(sizeof(struct foo) + sizeof(bar_t) * n);
  • ```
  • - The multiplication is performed inside the function, inside a check to prevent overflow.
  • However, as a general rule, when you multiply numbers, put first the value with the widest type, to avoid overflowing intermediate operations (read about precedence in operators).
  • ```c
  • int a, b;
  • size_t c, d;
  • ...
  • d = a * b * c; // might overflow `a * b` easily
  • d = c * a * b; // less likely
  • ```
  • ---
  • ### Use the type or the pointer name in _sizeof()_?
  • None of the alternatives is good.
  • If you use the type, then if you change the type of the pointer might introduce silent bugs in _malloc(3)_ calls, since there's no way that the compiler knows if your doing the right thing.
  • If you use the name, then you reduce ability to search in the code. Code is more often read (and searched) than modified. It's quite useful to be able to search through a code base for all allocations of a given type with something like the following.
  • ```sh
  • grep -rni 'alloc.*\bfoo_t)' src
  • ```
  • The solution comes thanks to the next question, which is about casting. As a starter, I'll say that in this case readability is preferable to safety; we'll try to make it safe somehow... continue reading.
  • ---
  • ### To cast or not to cast? That is the question.
  • The unsurprising answer, again, is that none of the alternatives is good.
  • Casting, in general, can disable many warnings, and is a dreaded thing that should be used very carefully. However, that doesn't apply to _malloc(3)_, since it (by returning `void *`) implicitly converts to _any_ pointer type, so we can't do more damage by forcing a conversion.
  • Casting also had issues regarding implicit functions, but those are gone for good (since C99), so this is a non-issue. If you lived in a cave for the last 24 years, please get out and see the light.
  • Casts still have issues, which is why they're not ideal:
  • - Clutters the code, considerably reducing readability.
  • - They aren't DRY.
  • So let's not write the cast (which is not the same as don't cast).
  • Casting the result of malloc is good because:
  • - It couples the call with the type of the pointer. Since the cast converts the `void *` to a non-`void` pointer, it no longer converts to anything implicitly. This means that if the type of the pointer ever changes, _malloc(3)_ calls assigned to that pointer will no longer compile, and we will be able to fix any compilation errors.
  • So, the solution is to write the cast inside a macro, which uses the same information that we will need for _sizeof()_, thus avoiding repeating ourselves, and also avoiding readability issues.
  • ```c
  • #define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
  • ```
  • which is to be used as this:
  • ```c
  • foo_t *p;
  • p = MALLOC(42, foo_t); // 42 elements of type foo_t.
  • ```
  • It's readable, it's concise, it's easily searchable, and it's safe.
  • There are several things to consider when calling the _malloc(3)_ family of functions:
  • - `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • - Use the type or the pointer name in `sizeof()`?
  • - To cast or not to cast?
  • TL;DR:
  • Use a simple and readable interface, and let it handle the safety for you.
  • ```c
  • foo_t *p;
  • p = MALLOC(nelem, foo_t);
  • ```
  • Let's answer the questions one by one.
  • ---
  • ### `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • None of the alternatives is good.
  • Use functions that take separate arguments:
  • - `calloc(3)` (ISO C)
  • - `reallocarray(3)` (several Unix systems)
  • I suggest writing your own _mallocarray()_ and _reallocarrayf()_ as wrappers around these. _reallocarrayf()_ is more complex (read about _reallocf(3)_), but _mallocarray()_ can be trivially implemented:
  • ```c
  • #define mallocarray(nmemb, size) reallocarray(NULL, nmemb, size)
  • ```
  • As a rule, I _always_ use array allocation functions, even if I only want 1 element:
  • ```c
  • foo_t *p;
  • // p = MALLOC(1, foo_t); // which expands to:
  • p = (foo_t *) mallocarray(1, sizeof(foo_t));
  • ```
  • This has several benefits:
  • - It clearly shows the number of elements I want. If it's 1, or if it's 42.
  • An exception is when allocating a structure with a flexible array member. In such case, you really need to call _malloc(3)_ with the precise size you want:
  • ```c
  • struct foo {
  • int a;
  • bar_t b[];
  • };
  • struct foo *p;
  • p = (struct foo *) malloc(sizeof(struct foo) + sizeof(bar_t) * n);
  • ```
  • - The multiplication is performed inside the function, inside a check to prevent overflow.
  • However, as a general rule, when you multiply numbers, put first the value with the widest type, to avoid overflowing intermediate operations (read about precedence in operators).
  • ```c
  • int a, b;
  • size_t c, d;
  • ...
  • d = a * b * c; // might overflow `a * b` easily
  • d = c * a * b; // less likely
  • ```
  • ---
  • ### Use the type or the pointer name in _sizeof()_?
  • None of the alternatives is good.
  • If you use the type, then if you change the type of the pointer might introduce silent bugs in _malloc(3)_ calls, since there's no way that the compiler knows if your doing the right thing.
  • If you use the name, then you reduce ability to search in the code. Code is more often read (and searched) than modified. It's quite useful to be able to search through a code base for all allocations of a given type with something like the following.
  • ```sh
  • grep -rni 'alloc.*\bfoo_t)' src
  • ```
  • The solution comes thanks to the next question, which is about casting. As a starter, I'll say that in this case readability is preferable to safety; we'll try to make it safe somehow... continue reading.
  • ---
  • ### To cast or not to cast? That is the question.
  • The unsurprising answer, again, is that none of the alternatives is good.
  • Casting, in general, can disable many warnings, and is a dreaded thing that should be used very carefully. However, that doesn't apply to _malloc(3)_, since it (by returning `void *`) implicitly converts to _any_ pointer type, so we can't do more damage by forcing a conversion.
  • Casting also had issues regarding implicit functions, but those are gone for good (since C99), so this is a non-issue. If you lived in a cave for the last 24 years, please get out and see the light.
  • Casts still have issues, which is why they're not ideal:
  • - Clutters the code, considerably reducing readability.
  • - They aren't DRY.
  • So let's not write the cast (which is not the same as don't cast).
  • Casting the result of _malloc(3)_ is good because:
  • - It couples the call with the type of the pointer. Since the cast converts the `void *` to a non-`void` pointer, it no longer converts to anything implicitly. This means that if the type of the pointer ever changes, _malloc(3)_ calls assigned to that pointer will no longer compile, and we will be able to fix any compilation errors.
  • So, the solution is to write the cast inside a macro, which uses the same information that we will need for _sizeof()_, thus avoiding repeating ourselves, and also avoiding readability issues.
  • ```c
  • #define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
  • ```
  • which is to be used as this:
  • ```c
  • foo_t *p;
  • p = MALLOC(42, foo_t); // 42 elements of type foo_t.
  • ```
  • It's readable, it's concise, it's easily searchable, and it's safe.
#5: Post edited by user avatar alx‭ · 2023-04-04T12:53:17Z (about 1 year ago)
  • There are several things to consider when calling the _malloc(3)_ family of functions:
  • - `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • - Use the type or the pointer name in `sizeof()`?
  • - To cast or not to cast?
  • TL;DR:
  • Use a simple and readable interface, and let it handle the safety for you.
  • ```c
  • foo_t *p;
  • p = MALLOC(nelem, foo_t);
  • ```
  • Let's answer the questions one by one.
  • ---
  • ### `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • None of the alternatives is good.
  • Use functions that take separate arguments:
  • - `calloc(3)` (ISO C)
  • - `reallocarray(3)` (several Unix systems)
  • I suggest writing your own _mallocarray()_ and _reallocarrayf()_ as wrappers around these. _reallocarrayf()_ is more complex (read about _reallocf(3)_), but _mallocarray()_ can be trivially implemented:
  • ```c
  • #define mallocarray(nmemb, size) reallocarray(NULL, nmemb, size)
  • ```
  • As a rule, I _always_ use array allocation functions, even if I only want 1 element:
  • ```c
  • foo_t *p;
  • // p = MALLOC(1, foo_t); // which expands to:
  • p = (foo_t *) mallocarray(1, sizeof(foo_t));
  • ```
  • This has several benefits:
  • - It clearly shows the number of elements I want. If it's 1, or if it's 42.
  • An exception is when allocating a structure with a flexible array member. In such case, you really need to call _malloc(3)_ with the precise size you want:
  • ```c
  • struct foo {
  • int a;
  • bar_t b[];
  • };
  • struct foo *p;
  • p = (struct foo *) malloc(sizeof(struct foo) + sizeof(bar_t) * n);
  • ```
  • - The multiplication is performed inside the function, inside a check to prevent overflow.
  • However, as a general rule, when you multiply numbers, put first the value with the widest type, to avoid overflowing intermediate operations (read about precedence in operators).
  • ```c
  • int a, b;
  • size_t c, d;
  • ...
  • d = a * b * c; // might overflow `a * b` easily
  • d = c * a * b; // less likely
  • ```
  • ---
  • ### Use the type or the pointer name in _sizeof()_?
  • None of the alternatives is good.
  • If you use the type, then if you change the type of the pointer might introduce silent bugs in _malloc(3)_ calls, since there's no way that the compiler knows if your doing the right thing.
  • If you use the name, then you reduce ability to search in the code. Code is more often read (and searched) than modified. It's quite useful to be able to search through a code base for all allocations of a given type with something like the following.
  • ```sh
  • grep -rn 'alloc.*\bfoo_t)' src
  • ```
  • The solution comes thanks to the next question, which is about casting. As a starter, I'll say that in this case readability is preferable to safety; we'll try to make it safe somehow... continue reading.
  • ---
  • ### To cast or not to cast? That is the question.
  • The unsurprising answer, again, is that none of the alternatives is good.
  • Casting, in general, can disable many warnings, and is a dreaded thing that should be used very carefully. However, that doesn't apply to _malloc(3)_, since it (by returning `void *`) implicitly converts to _any_ pointer type, so we can't do more damage by forcing a conversion.
  • Casting also had issues regarding implicit functions, but those are gone for good (since C99), so this is a non-issue. If you lived in a cave for the last 24 years, please get out and see the light.
  • Casts still have issues, which is why they're not ideal:
  • - Clutters the code, considerably reducing readability.
  • - They aren't DRY.
  • So let's not write the cast (which is not the same as don't cast).
  • Casting the result of malloc is good because:
  • - It couples the call with the type of the pointer. Since the cast converts the `void *` to a non-`void` pointer, it no longer converts to anything implicitly. This means that if the type of the pointer ever changes, _malloc(3)_ calls assigned to that pointer will no longer compile, and we will be able to fix any compilation errors.
  • So, the solution is to write the cast inside a macro, which uses the same information that we will need for _sizeof()_, thus avoiding repeating ourselves, and also avoiding readability issues.
  • ```c
  • #define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
  • ```
  • which is to be used as this:
  • ```c
  • foo_t *p;
  • p = MALLOC(42, foo_t); // 42 elements of type foo_t.
  • ```
  • It's readable, it's concise, it's easily searchable, and it's safe.
  • There are several things to consider when calling the _malloc(3)_ family of functions:
  • - `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • - Use the type or the pointer name in `sizeof()`?
  • - To cast or not to cast?
  • TL;DR:
  • Use a simple and readable interface, and let it handle the safety for you.
  • ```c
  • foo_t *p;
  • p = MALLOC(nelem, foo_t);
  • ```
  • Let's answer the questions one by one.
  • ---
  • ### `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • None of the alternatives is good.
  • Use functions that take separate arguments:
  • - `calloc(3)` (ISO C)
  • - `reallocarray(3)` (several Unix systems)
  • I suggest writing your own _mallocarray()_ and _reallocarrayf()_ as wrappers around these. _reallocarrayf()_ is more complex (read about _reallocf(3)_), but _mallocarray()_ can be trivially implemented:
  • ```c
  • #define mallocarray(nmemb, size) reallocarray(NULL, nmemb, size)
  • ```
  • As a rule, I _always_ use array allocation functions, even if I only want 1 element:
  • ```c
  • foo_t *p;
  • // p = MALLOC(1, foo_t); // which expands to:
  • p = (foo_t *) mallocarray(1, sizeof(foo_t));
  • ```
  • This has several benefits:
  • - It clearly shows the number of elements I want. If it's 1, or if it's 42.
  • An exception is when allocating a structure with a flexible array member. In such case, you really need to call _malloc(3)_ with the precise size you want:
  • ```c
  • struct foo {
  • int a;
  • bar_t b[];
  • };
  • struct foo *p;
  • p = (struct foo *) malloc(sizeof(struct foo) + sizeof(bar_t) * n);
  • ```
  • - The multiplication is performed inside the function, inside a check to prevent overflow.
  • However, as a general rule, when you multiply numbers, put first the value with the widest type, to avoid overflowing intermediate operations (read about precedence in operators).
  • ```c
  • int a, b;
  • size_t c, d;
  • ...
  • d = a * b * c; // might overflow `a * b` easily
  • d = c * a * b; // less likely
  • ```
  • ---
  • ### Use the type or the pointer name in _sizeof()_?
  • None of the alternatives is good.
  • If you use the type, then if you change the type of the pointer might introduce silent bugs in _malloc(3)_ calls, since there's no way that the compiler knows if your doing the right thing.
  • If you use the name, then you reduce ability to search in the code. Code is more often read (and searched) than modified. It's quite useful to be able to search through a code base for all allocations of a given type with something like the following.
  • ```sh
  • grep -rni 'alloc.*\bfoo_t)' src
  • ```
  • The solution comes thanks to the next question, which is about casting. As a starter, I'll say that in this case readability is preferable to safety; we'll try to make it safe somehow... continue reading.
  • ---
  • ### To cast or not to cast? That is the question.
  • The unsurprising answer, again, is that none of the alternatives is good.
  • Casting, in general, can disable many warnings, and is a dreaded thing that should be used very carefully. However, that doesn't apply to _malloc(3)_, since it (by returning `void *`) implicitly converts to _any_ pointer type, so we can't do more damage by forcing a conversion.
  • Casting also had issues regarding implicit functions, but those are gone for good (since C99), so this is a non-issue. If you lived in a cave for the last 24 years, please get out and see the light.
  • Casts still have issues, which is why they're not ideal:
  • - Clutters the code, considerably reducing readability.
  • - They aren't DRY.
  • So let's not write the cast (which is not the same as don't cast).
  • Casting the result of malloc is good because:
  • - It couples the call with the type of the pointer. Since the cast converts the `void *` to a non-`void` pointer, it no longer converts to anything implicitly. This means that if the type of the pointer ever changes, _malloc(3)_ calls assigned to that pointer will no longer compile, and we will be able to fix any compilation errors.
  • So, the solution is to write the cast inside a macro, which uses the same information that we will need for _sizeof()_, thus avoiding repeating ourselves, and also avoiding readability issues.
  • ```c
  • #define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
  • ```
  • which is to be used as this:
  • ```c
  • foo_t *p;
  • p = MALLOC(42, foo_t); // 42 elements of type foo_t.
  • ```
  • It's readable, it's concise, it's easily searchable, and it's safe.
#4: Post edited by user avatar alx‭ · 2023-04-04T12:52:50Z (about 1 year ago)
  • There are several things to consider when calling the _malloc(3)_ family of functions:
  • - `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • - Use the type or the pointer name in `sizeof()`?
  • - To cast or not to cast?
  • TL;DR:
  • Use a simple and readable interface, and let it handle the safety for you.
  • ```c
  • foo_t *p;
  • p = MALLOC(nelem, foo_t);
  • ```
  • Let's answer the questions one by one.
  • ---
  • ### `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • None of the alternatives is good.
  • Use functions that take separate arguments:
  • - `calloc(3)` (ISO C)
  • - `reallocarray(3)` (several Unix systems)
  • I suggest writing your own _mallocarray()_ and _reallocarrayf()_ as wrappers around these. _reallocarrayf()_ is more complex (read about _reallocf(3)_), but _mallocarray()_ can be trivially implemented:
  • ```c
  • #define mallocarray(nmemb, size) reallocarray(NULL, nmemb, size)
  • ```
  • As a rule, I _always_ use array allocation functions, even if I only want 1 element:
  • ```c
  • foo_t *p;
  • // p = MALLOC(1, foo_t); // which expands to:
  • p = (foo_t *) mallocarray(1, sizeof(foo_t));
  • ```
  • This has several benefits:
  • - It clearly shows the number of elements I want. If it's 1, or if it's 42.
  • An exception is when allocating a structure with a flexible array member. In such case, you really need to call _malloc(3)_ with the precise size you want:
  • ```c
  • struct foo {
  • int a;
  • bar_t b[];
  • };
  • struct foo *p;
  • p = (struct foo *) malloc(sizeof(struct foo) + sizeof(bar_t) * n);
  • ```
  • - The multiplication is performed inside the function, inside a check to prevent overflow.
  • However, as a general rule, when you multiply numbers, put first the value with the widest type, to avoid overflowing intermediate operations (read about precedence in operators).
  • ```c
  • int a, b;
  • size_t c, d;
  • ...
  • d = a * b * c; // might overflow `a * b` easily
  • d = c * a * b; // less likely
  • ```
  • ---
  • ### Use the type or the pointer name in _sizeof()_?
  • None of the alternatives is good.
  • If you use the type, then if you change the type of the pointer might introduce silent bugs in _malloc(3)_ calls, since there's no way that the compiler knows if your doing the right thing.
  • If you use the name, then you reduce ability to search in the code. Code is more often read (and searched) than modified. It's quite useful to be able to search through a code base for all allocations of a given type with something like the following.
  • ```sh
  • grep -rni 'alloc.*foo_t)' src
  • ```
  • The solution comes thanks to the next question, which is about casting. As a starter, I'll say that readability is preferable to theoretical safety; we'll try to make it safe somehow... continue reading.
  • ---
  • ### To cast or not to cast? That is the question.
  • The unsurprising answer, again, is that none of the alternatives is good.
  • Casting, in general, can disable many warnings, and is a dreaded thing that should be used very carefully. However, that doesn't apply to _malloc(3)_, since it (by returning `void *`) implicitly converts to _any_ pointer type, so we can't do more damage by forcing a conversion.
  • Casting also had issues regarding implicit functions, but those are gone for good (since C99), so this is a non-issue. If you lived in a cave for the last 24 years, please get out and see the light.
  • Casts still have issues, which is why they're not ideal:
  • - Clutters the code, considerably reducing readability.
  • - They aren't DRY.
  • So let's not write the cast (which is not the same as don't cast).
  • Casting the result of malloc is good because:
  • - It couples the call with the type of the pointer. Since the cast converts the `void *` to a non-`void` pointer, it no longer converts to anything implicitly. This means that if the type of the pointer ever changes, _malloc(3)_ calls assigned to that pointer will no longer compile, and we will be able to fix any compilation errors.
  • So, the solution is to write the cast inside a macro, which uses the same information that we will need for _sizeof()_, thus avoiding repeating ourselves, and also avoiding readability issues.
  • ```c
  • #define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
  • ```
  • which is to be used as this:
  • ```c
  • foo_t *p;
  • p = MALLOC(42, foo_t); // 42 elements of type foo_t.
  • ```
  • It's readable, it's concise, it's easily searchable, and it's safe.
  • There are several things to consider when calling the _malloc(3)_ family of functions:
  • - `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • - Use the type or the pointer name in `sizeof()`?
  • - To cast or not to cast?
  • TL;DR:
  • Use a simple and readable interface, and let it handle the safety for you.
  • ```c
  • foo_t *p;
  • p = MALLOC(nelem, foo_t);
  • ```
  • Let's answer the questions one by one.
  • ---
  • ### `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • None of the alternatives is good.
  • Use functions that take separate arguments:
  • - `calloc(3)` (ISO C)
  • - `reallocarray(3)` (several Unix systems)
  • I suggest writing your own _mallocarray()_ and _reallocarrayf()_ as wrappers around these. _reallocarrayf()_ is more complex (read about _reallocf(3)_), but _mallocarray()_ can be trivially implemented:
  • ```c
  • #define mallocarray(nmemb, size) reallocarray(NULL, nmemb, size)
  • ```
  • As a rule, I _always_ use array allocation functions, even if I only want 1 element:
  • ```c
  • foo_t *p;
  • // p = MALLOC(1, foo_t); // which expands to:
  • p = (foo_t *) mallocarray(1, sizeof(foo_t));
  • ```
  • This has several benefits:
  • - It clearly shows the number of elements I want. If it's 1, or if it's 42.
  • An exception is when allocating a structure with a flexible array member. In such case, you really need to call _malloc(3)_ with the precise size you want:
  • ```c
  • struct foo {
  • int a;
  • bar_t b[];
  • };
  • struct foo *p;
  • p = (struct foo *) malloc(sizeof(struct foo) + sizeof(bar_t) * n);
  • ```
  • - The multiplication is performed inside the function, inside a check to prevent overflow.
  • However, as a general rule, when you multiply numbers, put first the value with the widest type, to avoid overflowing intermediate operations (read about precedence in operators).
  • ```c
  • int a, b;
  • size_t c, d;
  • ...
  • d = a * b * c; // might overflow `a * b` easily
  • d = c * a * b; // less likely
  • ```
  • ---
  • ### Use the type or the pointer name in _sizeof()_?
  • None of the alternatives is good.
  • If you use the type, then if you change the type of the pointer might introduce silent bugs in _malloc(3)_ calls, since there's no way that the compiler knows if your doing the right thing.
  • If you use the name, then you reduce ability to search in the code. Code is more often read (and searched) than modified. It's quite useful to be able to search through a code base for all allocations of a given type with something like the following.
  • ```sh
  • grep -rn 'alloc.*\bfoo_t)' src
  • ```
  • The solution comes thanks to the next question, which is about casting. As a starter, I'll say that in this case readability is preferable to safety; we'll try to make it safe somehow... continue reading.
  • ---
  • ### To cast or not to cast? That is the question.
  • The unsurprising answer, again, is that none of the alternatives is good.
  • Casting, in general, can disable many warnings, and is a dreaded thing that should be used very carefully. However, that doesn't apply to _malloc(3)_, since it (by returning `void *`) implicitly converts to _any_ pointer type, so we can't do more damage by forcing a conversion.
  • Casting also had issues regarding implicit functions, but those are gone for good (since C99), so this is a non-issue. If you lived in a cave for the last 24 years, please get out and see the light.
  • Casts still have issues, which is why they're not ideal:
  • - Clutters the code, considerably reducing readability.
  • - They aren't DRY.
  • So let's not write the cast (which is not the same as don't cast).
  • Casting the result of malloc is good because:
  • - It couples the call with the type of the pointer. Since the cast converts the `void *` to a non-`void` pointer, it no longer converts to anything implicitly. This means that if the type of the pointer ever changes, _malloc(3)_ calls assigned to that pointer will no longer compile, and we will be able to fix any compilation errors.
  • So, the solution is to write the cast inside a macro, which uses the same information that we will need for _sizeof()_, thus avoiding repeating ourselves, and also avoiding readability issues.
  • ```c
  • #define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
  • ```
  • which is to be used as this:
  • ```c
  • foo_t *p;
  • p = MALLOC(42, foo_t); // 42 elements of type foo_t.
  • ```
  • It's readable, it's concise, it's easily searchable, and it's safe.
#3: Post edited by user avatar alx‭ · 2023-04-04T12:47:10Z (about 1 year ago)
  • There are several things to consider when calling the _malloc(3)_ family of functions:
  • - `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • - Use the type or the pointer name in `sizeof()`?
  • - To cast or not to cast?
  • Let's answer them one by one.
  • TL;DR:
  • Use a simple and readable interface, and let it handle the safety for you.
  • ```c
  • foo_t *p;
  • p = MALLOC(nelem, foo_t);
  • ```
  • ---
  • ### `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • None of the alternatives is good.
  • Use functions that take separate arguments:
  • - `calloc(3)` (ISO C)
  • - `reallocarray(3)` (several Unix systems)
  • I suggest writing your own _mallocarray()_ and _reallocarrayf()_ as wrappers around these. _reallocarrayf()_ is more complex (read about _reallocf(3)_), but _mallocarray()_ can be trivially implemented:
  • ```c
  • #define mallocarray(nmemb, size) reallocarray(NULL, nmemb, size)
  • ```
  • As a rule, I _always_ use array allocation functions, even if I only want 1 element:
  • ```c
  • foo_t *p;
  • // p = MALLOC(1, foo_t); // which expands to:
  • p = (foo_t *) mallocarray(1, sizeof(foo_t));
  • ```
  • This has several benefits:
  • - It clearly shows the number of elements I want. If it's 1, or if it's 42.
  • An exception is when allocating a structure with a flexible array member. In such case, you really need to call _malloc(3)_ with the precise size you want:
  • ```c
  • struct foo {
  • int a;
  • bar_t b[];
  • };
  • struct foo *p;
  • p = (struct foo *) malloc(sizeof(struct foo) + sizeof(bar_t) * n);
  • ```
  • - The multiplication is performed inside the function, inside a check to prevent overflow.
  • However, as a general rule, when you multiply numbers, put first the value with the widest type, to avoid overflowing intermediate operations (read about precedence in operators).
  • ```c
  • int a, b;
  • size_t c, d;
  • ...
  • d = a * b * c; // might overflow `a * b` easily
  • d = c * a * b; // less likely
  • ```
  • ---
  • ### Use the type or the pointer name in _sizeof()_?
  • None of the alternatives is good.
  • If you use the type, then if you change the type of the pointer might introduce silent bugs in _malloc(3)_ calls, since there's no way that the compiler knows if your doing the right thing.
  • If you use the name, then you reduce ability to search in the code. Code is more often read (and searched) than modified. It's quite useful to be able to search through a code base for all allocations of a given type with something like the following.
  • ```sh
  • grep -rni 'alloc.*foo_t)' src
  • ```
  • The solution comes thanks to the next question, which is about casting. As a starter, I'll say that readability is preferable to theoretical safety; we'll try to make it safe somehow... continue reading.
  • ---
  • ### To cast or not to cast? That is the question.
  • The unsurprising answer, again, is that none of the alternatives is good.
  • Casting, in general, can disable many warnings, and is a dreaded thing that should be used very carefully. However, that doesn't apply to _malloc(3)_, since it (by returning `void *`) implicitly converts to _any_ pointer type, so we can't do more damage by forcing a conversion.
  • Casting also had issues regarding implicit functions, but those are gone for good (since C99), so this is a non-issue. If you lived in a cave for the last 24 years, please get out and see the light.
  • Casts still have issues, which is why they're not ideal:
  • - Clutters the code, considerably reducing readability.
  • - They aren't DRY.
  • So let's not write the cast (which is not the same as don't cast).
  • Casting the result of malloc is good because:
  • - It couples the call with the type of the pointer. Since the cast converts the `void *` to a non-`void` pointer, it no longer converts to anything implicitly. This means that if the type of the pointer ever changes, _malloc(3)_ calls assigned to that pointer will no longer compile, and we will be able to fix any compilation errors.
  • So, the solution is to write the cast inside a macro, which uses the same information that we will need for _sizeof()_, thus avoiding repeating ourselves, and also avoiding readability issues.
  • ```c
  • #define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
  • ```
  • which is to be used as this:
  • ```c
  • foo_t *p;
  • p = MALLOC(42, foo_t); // 42 elements of type foo_t.
  • ```
  • It's readable, it's concise, it's easily searchable, and it's safe.
  • There are several things to consider when calling the _malloc(3)_ family of functions:
  • - `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • - Use the type or the pointer name in `sizeof()`?
  • - To cast or not to cast?
  • TL;DR:
  • Use a simple and readable interface, and let it handle the safety for you.
  • ```c
  • foo_t *p;
  • p = MALLOC(nelem, foo_t);
  • ```
  • Let's answer the questions one by one.
  • ---
  • ### `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • None of the alternatives is good.
  • Use functions that take separate arguments:
  • - `calloc(3)` (ISO C)
  • - `reallocarray(3)` (several Unix systems)
  • I suggest writing your own _mallocarray()_ and _reallocarrayf()_ as wrappers around these. _reallocarrayf()_ is more complex (read about _reallocf(3)_), but _mallocarray()_ can be trivially implemented:
  • ```c
  • #define mallocarray(nmemb, size) reallocarray(NULL, nmemb, size)
  • ```
  • As a rule, I _always_ use array allocation functions, even if I only want 1 element:
  • ```c
  • foo_t *p;
  • // p = MALLOC(1, foo_t); // which expands to:
  • p = (foo_t *) mallocarray(1, sizeof(foo_t));
  • ```
  • This has several benefits:
  • - It clearly shows the number of elements I want. If it's 1, or if it's 42.
  • An exception is when allocating a structure with a flexible array member. In such case, you really need to call _malloc(3)_ with the precise size you want:
  • ```c
  • struct foo {
  • int a;
  • bar_t b[];
  • };
  • struct foo *p;
  • p = (struct foo *) malloc(sizeof(struct foo) + sizeof(bar_t) * n);
  • ```
  • - The multiplication is performed inside the function, inside a check to prevent overflow.
  • However, as a general rule, when you multiply numbers, put first the value with the widest type, to avoid overflowing intermediate operations (read about precedence in operators).
  • ```c
  • int a, b;
  • size_t c, d;
  • ...
  • d = a * b * c; // might overflow `a * b` easily
  • d = c * a * b; // less likely
  • ```
  • ---
  • ### Use the type or the pointer name in _sizeof()_?
  • None of the alternatives is good.
  • If you use the type, then if you change the type of the pointer might introduce silent bugs in _malloc(3)_ calls, since there's no way that the compiler knows if your doing the right thing.
  • If you use the name, then you reduce ability to search in the code. Code is more often read (and searched) than modified. It's quite useful to be able to search through a code base for all allocations of a given type with something like the following.
  • ```sh
  • grep -rni 'alloc.*foo_t)' src
  • ```
  • The solution comes thanks to the next question, which is about casting. As a starter, I'll say that readability is preferable to theoretical safety; we'll try to make it safe somehow... continue reading.
  • ---
  • ### To cast or not to cast? That is the question.
  • The unsurprising answer, again, is that none of the alternatives is good.
  • Casting, in general, can disable many warnings, and is a dreaded thing that should be used very carefully. However, that doesn't apply to _malloc(3)_, since it (by returning `void *`) implicitly converts to _any_ pointer type, so we can't do more damage by forcing a conversion.
  • Casting also had issues regarding implicit functions, but those are gone for good (since C99), so this is a non-issue. If you lived in a cave for the last 24 years, please get out and see the light.
  • Casts still have issues, which is why they're not ideal:
  • - Clutters the code, considerably reducing readability.
  • - They aren't DRY.
  • So let's not write the cast (which is not the same as don't cast).
  • Casting the result of malloc is good because:
  • - It couples the call with the type of the pointer. Since the cast converts the `void *` to a non-`void` pointer, it no longer converts to anything implicitly. This means that if the type of the pointer ever changes, _malloc(3)_ calls assigned to that pointer will no longer compile, and we will be able to fix any compilation errors.
  • So, the solution is to write the cast inside a macro, which uses the same information that we will need for _sizeof()_, thus avoiding repeating ourselves, and also avoiding readability issues.
  • ```c
  • #define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
  • ```
  • which is to be used as this:
  • ```c
  • foo_t *p;
  • p = MALLOC(42, foo_t); // 42 elements of type foo_t.
  • ```
  • It's readable, it's concise, it's easily searchable, and it's safe.
#2: Post edited by user avatar alx‭ · 2023-04-04T12:45:48Z (about 1 year ago)
  • There are several things to consider when calling the _malloc(3)_ family of functions:
  • - `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • - Use the type or the pointer name in `sizeof()`?
  • - To cast or not to cast?
  • Let's answer them one by one.
  • TL;DR:
  • Use a simple and readable interface, and let it handle the safety for you.
  • ```c
  • foo_t *p;
  • p = MALLOC(nelem, foo_t);
  • ```
  • ---
  • ### `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • None of the alternatives is good.
  • Use functions that take separate arguments:
  • - `calloc(3)` (ISO C)
  • - `reallocarray(3)` (several Unix systems)
  • I suggest writing your own _mallocarray()_ and _reallocarrayf()_ as wrappers around these. _reallocarrayf()_ is more complex (read about _reallocf(3)_), but _mallocarray()_ can be trivially implemented:
  • ```c
  • #define mallocarray(nmemb, size) reallocarray(NULL, nmemb, size)
  • ```
  • As a rule, I _always_ use array allocation functions, even if I only want 1 element:
  • ```c
  • foo_t *p;
  • // p = MALLOC(1, foo_t); // which expands to:
  • p = (foo_t *) mallocarray(1, sizeof(foo_t));
  • ```
  • This has several benefits:
  • - It clearly shows the number of elements I want. If it's 1, or if it's 42.
  • An exception is when allocating a structure with a flexible array member. In such case, you really need to call _malloc(3)_ with the precise size you want:
  • ```c
  • struct foo {
  • int a;
  • bar_t b[];
  • };
  • struct foo *p;
  • p = (struct foo *) malloc(sizeof(struct foo) + sizeof(bar_t) * n);
  • ```
  • - The multiplication is performed inside the function, inside a check to prevent overflow.
  • However, as a general rule, when you multiply numbers, put first the value with the widest type, to avoid overflowing intermediate operations (read about precedence in operators).
  • ```c
  • int a, b;
  • size_t c, d;
  • ...
  • d = a * b * c; // might overflow `a * b` easily
  • d = c * a * b; // less likely
  • ```
  • ---
  • ### Use the type or the pointer name in _sizeof()_?
  • None of the alternatives is good.
  • If you use the type, then if you change the type of the pointer might introduce silent bugs in _malloc(3)_ calls, since there's no way that the compiler knows if your doing the right thing.
  • If you use the name, then you reduce ability to search in the code. Code is more often read (and searched) than modified. It's quite useful to be able to search through a code base for all allocations of a given type with something like the following.
  • ```sh
  • grep -rni 'alloc.*foo_t)' src
  • ```
  • The solution comes thanks to the next question, which is about casting. As a starter, I'll say that readability is preferable to theoretical safety; we'll try to make it safe somehow... continue reading.
  • ---
  • ### To cast or not to cast? That is the question.
  • The unsurprising answer, again, is that none of the alternatives is good.
  • Casting, in general, can disable many warnings, and is a dreaded thing that should be used very carefully. However, that doesn't apply to _malloc(3)_, since it (by returning `void *`) implicitly converts to _any_ pointer type, so we can't do and damage by forcing a conversion.
  • Casting also had issues regarding implicit functions, but those are gone for good (since C99), so this is a non-issue. If you lived in a cave for the last 24 years, please get out and see the light.
  • Casts still have issues, which is why they're not ideal:
  • - Clutters the code, considerably reducing readability.
  • - They aren't DRY.
  • So let's not write the cast (which is not the same as don't cast).
  • Casting the result of malloc is good because:
  • - It couples the call with the type of the pointer. Since the cast converts the `void *` to a non-`void` pointer, it no longer converts to anything implicitly. This means that if the type of the pointer ever changes, _malloc(3)_ calls assigned to that pointer will no longer compile, and we will be able to fix any compilation errors.
  • So, the solution is to write the cast inside a macro, which uses the same information that we will need for _sizeof()_, thus avoiding repeating ourselves, and also avoiding readability issues.
  • ```c
  • #define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
  • ```
  • which is to be used as this:
  • ```c
  • foo_t *p;
  • p = MALLOC(42, foo_t); // 42 elements of type foo_t.
  • ```
  • It's readable, it's concise, it's easily searchable, and it's safe.
  • There are several things to consider when calling the _malloc(3)_ family of functions:
  • - `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • - Use the type or the pointer name in `sizeof()`?
  • - To cast or not to cast?
  • Let's answer them one by one.
  • TL;DR:
  • Use a simple and readable interface, and let it handle the safety for you.
  • ```c
  • foo_t *p;
  • p = MALLOC(nelem, foo_t);
  • ```
  • ---
  • ### `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
  • None of the alternatives is good.
  • Use functions that take separate arguments:
  • - `calloc(3)` (ISO C)
  • - `reallocarray(3)` (several Unix systems)
  • I suggest writing your own _mallocarray()_ and _reallocarrayf()_ as wrappers around these. _reallocarrayf()_ is more complex (read about _reallocf(3)_), but _mallocarray()_ can be trivially implemented:
  • ```c
  • #define mallocarray(nmemb, size) reallocarray(NULL, nmemb, size)
  • ```
  • As a rule, I _always_ use array allocation functions, even if I only want 1 element:
  • ```c
  • foo_t *p;
  • // p = MALLOC(1, foo_t); // which expands to:
  • p = (foo_t *) mallocarray(1, sizeof(foo_t));
  • ```
  • This has several benefits:
  • - It clearly shows the number of elements I want. If it's 1, or if it's 42.
  • An exception is when allocating a structure with a flexible array member. In such case, you really need to call _malloc(3)_ with the precise size you want:
  • ```c
  • struct foo {
  • int a;
  • bar_t b[];
  • };
  • struct foo *p;
  • p = (struct foo *) malloc(sizeof(struct foo) + sizeof(bar_t) * n);
  • ```
  • - The multiplication is performed inside the function, inside a check to prevent overflow.
  • However, as a general rule, when you multiply numbers, put first the value with the widest type, to avoid overflowing intermediate operations (read about precedence in operators).
  • ```c
  • int a, b;
  • size_t c, d;
  • ...
  • d = a * b * c; // might overflow `a * b` easily
  • d = c * a * b; // less likely
  • ```
  • ---
  • ### Use the type or the pointer name in _sizeof()_?
  • None of the alternatives is good.
  • If you use the type, then if you change the type of the pointer might introduce silent bugs in _malloc(3)_ calls, since there's no way that the compiler knows if your doing the right thing.
  • If you use the name, then you reduce ability to search in the code. Code is more often read (and searched) than modified. It's quite useful to be able to search through a code base for all allocations of a given type with something like the following.
  • ```sh
  • grep -rni 'alloc.*foo_t)' src
  • ```
  • The solution comes thanks to the next question, which is about casting. As a starter, I'll say that readability is preferable to theoretical safety; we'll try to make it safe somehow... continue reading.
  • ---
  • ### To cast or not to cast? That is the question.
  • The unsurprising answer, again, is that none of the alternatives is good.
  • Casting, in general, can disable many warnings, and is a dreaded thing that should be used very carefully. However, that doesn't apply to _malloc(3)_, since it (by returning `void *`) implicitly converts to _any_ pointer type, so we can't do more damage by forcing a conversion.
  • Casting also had issues regarding implicit functions, but those are gone for good (since C99), so this is a non-issue. If you lived in a cave for the last 24 years, please get out and see the light.
  • Casts still have issues, which is why they're not ideal:
  • - Clutters the code, considerably reducing readability.
  • - They aren't DRY.
  • So let's not write the cast (which is not the same as don't cast).
  • Casting the result of malloc is good because:
  • - It couples the call with the type of the pointer. Since the cast converts the `void *` to a non-`void` pointer, it no longer converts to anything implicitly. This means that if the type of the pointer ever changes, _malloc(3)_ calls assigned to that pointer will no longer compile, and we will be able to fix any compilation errors.
  • So, the solution is to write the cast inside a macro, which uses the same information that we will need for _sizeof()_, thus avoiding repeating ourselves, and also avoiding readability issues.
  • ```c
  • #define MALLOC(n, type) ((type *) mallocarray(n, sizeof(type)))
  • ```
  • which is to be used as this:
  • ```c
  • foo_t *p;
  • p = MALLOC(42, foo_t); // 42 elements of type foo_t.
  • ```
  • It's readable, it's concise, it's easily searchable, and it's safe.
#1: Initial revision by user avatar alx‭ · 2023-04-04T12:45:00Z (about 1 year ago)
There are several things to consider when calling the _malloc(3)_ family of functions:

-  `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?
-  Use the type or the pointer name in `sizeof()`?
-  To cast or not to cast?

Let's answer them one by one.

TL;DR:

Use a simple and readable interface, and let it handle the safety for you.

```c
foo_t  *p;

p = MALLOC(nelem, foo_t);
```

---

### `nelem * sizeof(elem)` or `sizeof(elem) * nelem`?

None of the alternatives is good.

Use functions that take separate arguments:

-  `calloc(3)` (ISO C)
-  `reallocarray(3)` (several Unix systems)

I suggest writing your own _mallocarray()_ and _reallocarrayf()_ as wrappers around these.  _reallocarrayf()_ is more complex (read about _reallocf(3)_), but _mallocarray()_ can be trivially implemented:

```c
#define mallocarray(nmemb, size)  reallocarray(NULL, nmemb, size)
```

As a rule, I _always_ use array allocation functions, even if I only want 1 element:

```c
foo_t *p;

// p = MALLOC(1, foo_t);  // which expands to:

p = (foo_t *) mallocarray(1, sizeof(foo_t));
```

This has several benefits:

-  It clearly shows the number of elements I want.  If it's 1, or if it's 42.

   An exception is when allocating a structure with a flexible array member.  In such case, you really need to call _malloc(3)_ with the precise size you want:

```c
struct foo {
    int    a;
    bar_t  b[];
};

struct foo *p;

p = (struct foo *) malloc(sizeof(struct foo) + sizeof(bar_t) * n);
```

-  The multiplication is performed inside the function, inside a check to prevent overflow.

   However, as a general rule, when you multiply numbers, put first the value with the widest type, to avoid overflowing intermediate operations (read about precedence in operators).

```c
int     a, b;
size_t  c, d;

...

d = a * b * c;  // might overflow `a * b` easily
d = c * a * b;  // less likely
```

---

### Use the type or the pointer name in _sizeof()_?

None of the alternatives is good.

If you use the type, then if you change the type of the pointer might introduce silent bugs in _malloc(3)_ calls, since there's no way that the compiler knows if your doing the right thing.

If you use the name, then you reduce ability to search in the code.  Code is more often read (and searched) than modified.  It's quite useful to be able to search through a code base for all allocations of a given type with something like the following.

```sh
grep -rni 'alloc.*foo_t)' src
```

The solution comes thanks to the next question, which is about casting.  As a starter, I'll say that readability is preferable to theoretical safety; we'll try to make it safe somehow... continue reading.

---

### To cast or not to cast?  That is the question.

The unsurprising answer, again, is that none of the alternatives is good.

Casting, in general, can disable many warnings, and is a dreaded thing that should be used very carefully.  However, that doesn't apply to _malloc(3)_, since it (by returning `void *`) implicitly converts to _any_ pointer type, so we can't do and damage by forcing a conversion.

Casting also had issues regarding implicit functions, but those are gone for good (since C99), so this is a non-issue.  If you lived in a cave for the last 24 years, please get out and see the light.

Casts still have issues, which is why they're not ideal:

-  Clutters the code, considerably reducing readability.
-  They aren't DRY.

So let's not write the cast (which is not the same as don't cast).

Casting the result of malloc is good because:

-  It couples the call with the type of the pointer.  Since the cast converts the `void *` to a non-`void` pointer, it no longer converts to anything implicitly.  This means that if the type of the pointer ever changes, _malloc(3)_ calls assigned to that pointer will no longer compile, and we will be able to fix any compilation errors.

So, the solution is to write the cast inside a macro, which uses the same information that we will need for _sizeof()_, thus avoiding repeating ourselves, and also avoiding readability issues.

```c
#define MALLOC(n, type)  ((type *) mallocarray(n, sizeof(type)))
```

which is to be used as this:

```c
foo_t  *p;

p = MALLOC(42, foo_t);  // 42 elements of type foo_t.
```

It's readable, it's concise, it's easily searchable, and it's safe.