简体   繁体   中英

How to do always the same things just before 'return' when a function has a lot of 'return's?

I've a big function which allocates 2 arrays in the heap memory and returns many times in many different places. I would like to make the function call delete[] for my 2 arrays whenever she returns, without having to write delete[] s before each return .

int function(int a)
{
    size_t heap_arr1_len{100};
    int* heap_arr1{new int[heap_arr1_len]};
    
    size_t heap_arr2_len{200}; 
    int* heap_arr2{new int[heap_arr2_len]};
    
    //I was thinking of something similar to:
    struct at_return{
        ~at_return()
        {
        delete[] heap_arr1;
        delete[] heap_arr2;
        }
    } at_return;

    /*...............
    .................
    ......return 0;*/
    /*...............
    .....return 10;*/
    //ecc.
}

but with a compilation-time error i've figured out that a struct can't access the local variables of the function which is contained in.

What would you do in order to avoid to having to write delete[] heap_arr1; , delete[] heap_arr2; each time before each return ?

Don't allocate memory manually using new , use std::vector instead:

size_t heap_arr1_len = 100;
std::vector<int> heap_arr1(heap_arr1_len);

Then you don't need to worry about delete .


But using a destructor like this is in fact a great idea, assuming no suitable wrapper class exists. This trick is known as a scope guard . And here's a working implementation .

It could be useful eg when dealing with C libraries, which can't provide classes with destructors. You could write a reusable wrapper class with a destructor, or you could use a scope guard as an ad-hoc solution.

#include <memory>

int function(int a)
{
    size_t heap_arr1_len{100};
    std::unique_ptr<int[]> heap_arr1{new int[heap_arr1_len]};

    // Etc
}

If you need the underlying pointer for your file reading/writing functions, use heap_arr1.get().

I use a can_continue method so there is only one entry and one exit (MISRA rule).
First set a Boolean variable:

bool can_continue = true;

The pattern then becomes:

if (can_continue)
{
   // do some work
   // set can_continue to false to return unexpectedly
}

It may not be the fastest code, but it meets the criteria for one entry and one exit.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM