I\'m investigating a memory leak and from what I see, the problem looks like this:
int main(){
char *cp = 0;
func(cp);
//code
delete[] cp;
}
voi
The function is only changing a COPY of cp
. Use a reference instead.
Although references are wonderful in offering an intuitive abstraction, enhanced further by C++11 rvalue references to allow function chaining (and other esoteric coding), it is arguable that they provide any safety (viz why is a reference considered safer than a pointer) There are instances where it is better to resolve the above with a pointer to pointer function argument. Specifically when there is the need to maintain a similar codebase in ansi c and c++.
#include <iostream>
using namespace std;
void func(char ** cp) {
*cp = new char[100];
//do something useful
(*cp)[0] = 'A';
}
void func(char *& cp) {
cp = new char[100];
//do something useful
cp[0] = 'B';
}
int main(int argc, char** argv) {
char * cp;
//pointer to pointer
func(&cp);
cout << "Index 0 : " << cp[0] << '\n' << flush;
delete[] cp; //remember to delete!!
//pointer to ref
func(cp);
cout << "Index 0: " << cp[0] << '\n' << flush;
delete[] cp;
return 0;
}
Of course the disposal of memory resources out of the scope of the instatiating function disobeys RAII.
You're passing in cbuf
, not cp
.
As GMan and Neil mentioned, in order to work you will have to change func to:
char* func();
or void func(char*& p);
which will solve your immediate problem.
There is, however, a maintenance problem. In either case, func returns a pointer. What is not clear to the user of func is that returned pointer will have to be deleted. For this reason, generally avoid this construct unless 100% necessary. Rather:
So for C++ code,I would recommend:
class CBuf
{
public
CBuf()
{
iBuf = new char[100];
}
~CBuf
{
delete[] iBuf;
}
char* func()
{
//do stuff;
return iBuf;
}
private:
char* iBuf;
};
int main()
{
CBuf cb;
char* mychar = cb.func();
//do stuff with character array
//destructor gets called here because cb goes out of scope
}
However, in C programming especially, it might be 100% necessary to have some sort function to create the array. Therefore in C programming you can replace the destructor with a CreateCBuf
and DestroyCBuf
function. In this way the user of your library will know that the buffer returned needs to be destroyed.
You are assigning cp
the value of the allocated memory. However, that's a variable on the stack: a copy of the cp
in main! cp
is local to the function you're in.
What you want is a reference:
void func(char *& cp)
This will alias cp
to be the parameter passed in.
void func(char *cp){
cp = new char[100];
}
In this function, char *cp is a "pointer being passed by copy" what means that they are pointing to the same memory address but they are not the same pointer. When you change the pointer inside, making it to point to somewhere else, the original pointer that has been passed will keep pointing to 0.