3 ms·
There are three macros which I find indispensable and which I use in all my C projects, namely LEN, NEW and NEW_ARRAY. I keep them in a file named Util.h: #i
by augustk 4y ago
There are three macros which I find indispensable and which I use in all my C projects, namely LEN, NEW and NEW_ARRAY. I keep them in a file named Util.h:
#ifndef UTIL_H
#define UTIL_H
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LEN(arr) (sizeof (arr) / sizeof (arr)[0])
#define NEW_ARRAY(ptr, n) \
(ptr) = malloc((n) * sizeof (ptr)[0]); \
if ((ptr) == NULL) { \
fprintf(stderr, "Memory allocation failed: %s\n", strerror(errno)); \
exit(EXIT_FAILURE); \
}
#define NEW(ptr) NEW_ARRAY(ptr, 1)
#endif
With these in place, working with arrays and dynamic memory is safer, less verbose and readability is improved.
- GnarfGnarf 4y agoI found a lot of bugs went away when I switched to STL (Standard Template Library) arrays and ditched managing my own memory. That's C++, I guess it's not available in straight C?
- krapp 4y ago>That's C++, I guess it's not available in straight C? No, because C doesn't have templates. The best you can do for a "vector" in C is macros like above, that also realloc, or write an API around structs for each type.
- GnarfGnarf 4y agoToo bad. STL deque's are non-contiguous, allow for much bigger arrays. I had an application that used vector<>, ran out of contiguous memory. deque<> solved the problem.
- augustk 4y agoIt's even easier if you use a garbage collector, like for instance libgc. Then you just replace (ptr) = malloc((n) * sizeof (ptr)[0]); with (ptr) = GC_MALLOC((n) * sizeof (ptr)[0]); in the macro and don't have to worry about calling free.
- Gibbon1 4y agoWith gcc you can use this to get the elements of an array. // will barf if fed a pointer #define sizeof_array(arr) \ (sizeof(arr) / sizeof((arr)[0]) \ + sizeof(typeof(int[1 - 2 * \ !!__builtin_types_compatible_p(typeof(arr), \ typeof(&arr[0]))])) * 0)