Smart pointers/safe memory management for C?

后端 未结 9 553
闹比i
闹比i 2020-12-07 17:31

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 memo

9条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-12-07 18:10

    You cannot do smart pointers in C because it does not provide necessary syntax, but you can avoid leaks with practice. Write the resource release code immediately after you allocated it. So whenever you write a malloc, you should write the corresponding free immediately in a cleanup section.

    In C I see the 'GOTO cleanup' pattern a lot:

    int foo()
    {
        int *resource = malloc(1000);
        int retVal = 0;
        //...
        if (time_to_exit())
        {
            retVal = 123;
            goto cleanup;
        }
    cleanup:
        free(resource);
        return retVal;
    }
    

    In C we also use a lot of contexts which allocate stuff, the same rule can be applied for that too:

    int initializeStuff(Stuff *stuff)
    {
        stuff->resource = malloc(sizeof(Resource));
        if (!stuff->resource) 
        {
            return -1; ///< Fail.
        }
        return 0; ///< Success.
    }
    
    void cleanupStuff(Stuff *stuff)
    {
        free(stuff->resource);
    }
    

    This is analogous to the object constructors and destructors. As long as you don't give away the allocated resources to other objects it won't leak and pointers won't dangle.

    It's not difficult to write a custom allocator that tracks allocations and writes leaking blocks atexit.

    If you need to give away pointers to the allocated resources you can create wrapper contexts for it and each object owns a wrapper context instead of the resource. These wrappers share the resource and a counter object, which tracks the usage and frees the objects when no one uses it. This is how C++11's shared_ptr and weak_ptr works. It's written in more detail here: How does weak_ptr work?

提交回复
热议问题