Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Smart pointers/safe memory management for C?

I, and I think many others, have had great success using smart pointers to wrap up unsafe memory operations in C++, using things like RAII, et cetera. However, wrapping memory management is easier to implement when you have destructors, classes, operator overloading, et cetera.

For someone writing in raw C99, where could you point (no pun intended) to help with safe memory management?

Thanks.

like image 971
mannicken Avatar asked Apr 28 '09 21:04

mannicken


People also ask

Are smart pointers memory safe?

In modern C++ programming, the Standard Library includes smart pointers, which are used to help ensure that programs are free of memory and resource leaks and are exception-safe.

Can you have memory leaks with smart pointers?

Even when using smart pointers, is it still possible to have memory leak ? Yes, if you are not careful to avoid creating a cycle in your references.

Do you need a destructor with smart pointers?

Boost smart pointers by themselves don't have anything to do with the need for a destructor. All they do is remove the need for you to call delete on the allocated memory that they are effectively managing.

What problem does using smart pointers help prevent?

Smart pointers try to prevent memory leaks by making the resource deallocation automatic: when the pointer to an object (or the last in a series of pointers) is destroyed, for example because it goes out of scope, the pointed object is destroyed too.


3 Answers

The question is a bit old, but I figured I would take the time to link to my smart pointer library for GNU compilers (GCC, Clang, ICC, MinGW, ...).

This implementation relies on the cleanup variable attribute, a GNU extension, to automatically free the memory when going out of scope, and as such, is not ISO C99, but C99 with GNU extensions.

Example:

simple1.c:

#include <stdio.h> #include <csptr/smart_ptr.h>  int main(void) {     smart int *some_int = unique_ptr(int, 1);      printf("%p = %d\n", some_int, *some_int);      // some_int is destroyed here     return 0; } 

Compilation & Valgrind session:

$ gcc -std=gnu99 -o simple1 simple1.c -lcsptr $ valgrind ./simple1 ==3407== Memcheck, a memory error detector ==3407== Copyright (C) 2002-2013, and GNU GPL\'d, by Julian Seward et al. ==3407== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info ==3407== Command: ./simple1  ==3407== 0x53db068 = 1 ==3407== ==3407== HEAP SUMMARY: ==3407==     in use at exit: 0 bytes in 0 blocks ==3407==   total heap usage: 1 allocs, 1 frees, 48 bytes allocated ==3407== ==3407== All heap blocks were freed -- no leaks are possible ==3407== ==3407== For counts of detected and suppressed errors, rerun with: -v ==3407== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 
like image 125
Snaipe Avatar answered Sep 23 '22 14:09

Snaipe


It's difficult to handle smart pointers in raw C, since you don't have the language syntax to back up the usage. Most of the attempts I've seen don't really work, since you don't have the advantages of destructors running when objects leave scope, which is really what makes smart pointers work.

If you're really worried about this, you might want to consider just directly using a garbage collector, and bypassing the smart pointer requirement altogether.

like image 27
Reed Copsey Avatar answered Sep 24 '22 14:09

Reed Copsey


Another approach that you might want to consider is the pooled memory approach that Apache uses. This works exceptionally well if you have dynamic memory usage that is associated with a request or other short-lived object. You can create a pool in your request structure and make sure that you always allocate memory from the pool and then free the pool when you are done processing the request. It doesn't sound nearly as powerful as it is once you have used it a little. It is almost as nice as RAII.

like image 23
D.Shawley Avatar answered Sep 22 '22 14:09

D.Shawley