-1

my question can be briefly shown as the following example.

void func(int n){

    char *p = (char*)malloc(n);

    // some codes

    memset(p,0,sizeof(name));

    // free(p); // Commenting this line represents that I forget to release the allocated memory.
}


int main(){

    // some codes

    for (int i; i < Nl; i++){

        func(100);

        // How can I release the allocated memory of p outside of the func?
    }

}

I whish to release the allocated memory, which is allocated in a function, outside of this function.

Thank you.

  • Terminate the process and the OS will free the memory. ([c - What REALLY happens when you don't free after malloc? - Stack Overflow](https://stackoverflow.com/questions/654754/what-really-happens-when-you-dont-free-after-malloc)) – MikeCAT Oct 09 '20 at 17:44
  • A program must have a pointer to the start of an allocated block in order to free that block. In the example program, the necessary pointer is no longer available once the function returns, leaving the program no way to free the allocated memory. This is called a "memory leak". You cannot recover from one, short of terminating the program; instead, you need to avoid them by exercising good discipline and careful programming practices. – John Bollinger Oct 09 '20 at 18:02
  • 1
    "if I forgot to release the memory" What are you trying to do? If you know that you forgot to release the memory, just change the code to release the memory. If you want to know techniques for avoiding forgetting, use `std::unique_ptr` or `std::vector`. If you want to completely avoid the possibility in C, which doesn't have these, perhaps you could use a garbage collector. – Justin Oct 09 '20 at 18:08
  • Suggestion: do not try to write multi-language source files (except for some fun). – pmg Oct 22 '20 at 11:55

4 Answers4

6

The pointer in question is not returned from the function in any way, so if you don't free it in the function then the memory is leaked. You would need to modify the function to either assign the pointer to a global, return it from the function, or assign it to a dereferenced pointer passed to the function.

If your goal is to find and fix memory leaks in your program, there are tools such as valgrind which can help you with that.

dbush
  • 205,898
  • 23
  • 218
  • 273
1

To solve the problem it's better to use std::unique_ptr. If you use smart pointer it will be released whenever it's not required anymore. Foe example :

void my_func()
{
    std::unique_ptr<int> valuePtr(new int(15));
    int x = 45;
    // ...
    if (x == 45)
        return;   // no memory leak anymore!
    // ...
}

You can check the link to study more : https://en.cppreference.com/book/intro/smart_pointers

mhheydarchi
  • 79
  • 1
  • 5
1

Two solutions in C

a) use VLA

void foo(int n) {
    char p[n];
    // use p
    // no need to free, p automatically releases its memory
}

b) return the pointer to the caller

char *foo(int n) {
    char *p = malloc(n);
    // use p
    return p;
}

int main(void) {
    char *bar = foo(100);
    free(bar);
}
pmg
  • 106,608
  • 13
  • 126
  • 198
0

If I understand you correctly, you are struggling with the basic concept of memory management. Looking at your code you are malloc, which is a core C memory management aspect, although you tagged the question as C and C++. I can go into depth on why there ain't a thing like C/C++, though it's better explained here: https://cor3ntin.github.io/posts/c/

One of the elements C and C++ programmers disagree is the use of malloc, which is standard in C and and only used in exceptional cases in C++.

If we look from a C++ standpoint, I'd argue you should be learning it with a recent version. Here the answer is simple: use std::make_unique:

auto p = std::make_unique<char[]>(n);

Or in this case as you are trying to do something with strings, just use std::string. Trust me, doing so will prevent a lot of grief. Let me also remark that you often don't need memory allocations, more about that can be found here: https://stackoverflow.com/a/53898150/2466431

If you however ain't programming C++, you can use malloc. Here it is important to understand that every pointer returned by malloc ends up as an argument for free. (Exceptions on this ain't for beginners) After you call free, you can't use what the pointer points to, not the value stored in the pointer. Calling free twice for the same pointer is also an issue.

Hence, unlike in the C++ code where the memory gets freed when no longer used. You need to keep detailed attention for this and call free.

In your function, uncommenting the free is the correct solution. If you have the intention to let the data outlive the function call, you should be returning the pointer to the caller, this is than responsible for the ownership:

char * func(int n){
    char *p = (char*)malloc(n);
    // some codes
    memset(p,0,sizeof(name));
    return p;
}

int main(){
    // some codes
    for (int i; i < Nl; i++){
        char *s = func(100);
        free(s);
    }

}

Let me show the same with the previously mentioned C++:

#include <memory>
std::unique_ptr<char[]> func(int n){
    auto p = std::make_unique<char[]>(n);
    // some codes
    return p;
}

int main(){
    // some codes
    for (int i; i < Nl; i++){
        auto s = func(100);
    }

}

Or using std::string

#include <string>
std::string func(int n){
    auto p = std::string(n, '\0');
    // some codes
    return p;
}

int main(){
    // some codes
    for (int i; i < Nl; i++){
        auto s = func(100);
    }

}

JVApen
  • 11,008
  • 5
  • 31
  • 67