1

From 21st-Century C:

The easiest way to avoid bugs related to malloc is not to use malloc.

and

Production code tends to have few uses of malloc, typically wrapped in new/copy/free functions so the main code doesn’t have to deal further with memory management.

Primary Question: Can someone provide a super simple, idiomatic example of how one might use function wrappers like this to subvert the direct usage of free and malloc?

Secondary Question (Optional): In particular, can the clever use of such functions emulate the behavior (or even some of the behavior) of the C++ shared_ptr and unique_ptr? That is, can using such functions free you from the worry that you might accidently free dangling pointers and/or create leaks? Or is that simply impossible in C, even with the use of such functions?

George
  • 6,927
  • 4
  • 34
  • 67
  • 1
    About the secondary question, the C++ smart pointers rely too much on RAII, which only works because of automatic calls to destructors when local variables go out of scope. It is possible to emulate some of that functionality with macros, but far from reliable as it is in C++. – André Sassi Dec 17 '16 at 21:30
  • 1
    You cannot encapsulate away memory management by wrapping `malloc`. I don't know what the author of that book was smoking. – n. m. could be an AI Dec 17 '16 at 21:33
  • @n.m. I imagine he/she is talking about adding compile time type checking. –  Dec 17 '16 at 21:35
  • "*Can someone provide a super simple, idiomatic example ...*" doesn't *this* book you read provide some? – alk Dec 18 '16 at 10:27
  • "*Or is that simply impossible in C*" Yes, at least if you do not take care of what you are doing. C is "doing dangerous", as you tend to do mostly when *rolling your own*. "*... even with the use of such functions?*" Yes, again. – alk Dec 18 '16 at 10:32

2 Answers2

2

Something like this? (It will add some compile time checking of the types, but that's about it)

typedef struct a_ {
   int a;
   int b;
} a;

a *new_a() {
     return malloc(sizeof(a));
}

void free_a(a *p) {
     free(p);
}

Secondary question: Smart pointers/safe memory management for C?

Community
  • 1
  • 1
1

Here are two popular idioms:

‌1. A wrapper around malloc so that it "never fails":

void safe_malloc(size_t size)
{
    char *ret = malloc(size);
    if(ret == NULL) {
        fprintf(stderr, "out of memory\n");
        exit(1);
    }
    return ret;
}

This way, you can call safe_malloc wherever you want, and never worry about checking its return value. But you can only use this idiom in a program where you don't mind the possibility that the program will spontaneously exit if malloc fails (i.e. if there's no data loss to be worried about in that case).

‌2. A "new" function for a particular structure type:

struct whatever *new_whatever()
{
    struct whatever *ret = safe_malloc(sizeof(*ret));
    initialize_whatever(ret);
    return ret;
}

I'm not sure these are what you're looking for, and I'm not sure they're what Ben Klemens is talking about. These don't really "solve" the memory allocation problem -- it can still be quite a nuisance -- but they help somewhat.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103