I am trying a code which Goes like this:-
class test{
int test_int;
public:
virtual int show()
{
return test_int;
}
void set_int(int data){
std::cout<<"received data "<< data <<endl;
test_int = data;
}
};
int main()
{
test *ptr=new test();
ptr=NULL;
ptr->set_int(5);
return 0;
}
Now the problem i am facing is my program after printing the data which i am sending through set_int function got printed but the program crashes just after the completition of the function(set_int).
Am i doing any mistake that is not according to the language standards?
TIA.
Am i doing any mistake that is not according to the language standards?
Yes, you are.
You may not call member functions on a pointer that does not point to a valid object of that type. A null pointer never points to a valid object.
The trivial fix here is to remove the line ptr=NULL;. That way ptr still points to an object when the member function is invoked. This also allows you to fix the memory leak by deleting the pointer later. As a sidenote: avoid manual memory management.
You have pointer to test (test*) set to dynamicaly allocated memory representing instance of that class.
Right after that, you wrote "Nah, I do not need it anymore" and you forget where that newly allocated memory was.
Finally, you are trying to access an object on address 0, which is an invalid operation and will cause runtime error.
You probably meant to do this
int main()
{
test *ptr = new test();
ptr->set_int(5);
// ptr = NULL; // wont free the memory allocated by new
delete ptr; // memory deallocation
ptr = NULL; // now we can safely forget that address (which is now invalid anyways)
return 0;
}
Related
I heard a lot of memory leak vulnerability, but I could not find a real work example of memory leak, could you provide a real work example of memory leak, maybe of some big open source project and explain the solution to me
thx.
It's really simple actually. In your main put:
char* c = new char[4];
Then exit. That's a memory leak. Any new that doesn't get followed by delete is a leak.
This answer has some good examples, but like my comment has said, it will be fairly hard to find a released application with a leak that an outside observer can look at and easily identify.
I am screaming, cursing and yelling everyday about code like this in our (huge) legacy code base:
// returns raw pointer with changing conventions who's the owner...
HelpFoo* Foo::GetFoo(Bar* pBar, OtherFoo* pFoo)
{
// all 'local' variables even those allocated on freestore declared
// and initialized in a large block at the beginning of the function/method
HelpFoo *A = new HelpFoo;
OtherHelpFoo *B, *C;
EvenMore *D = new EvenMore;
// and so on, these blocks can be huge...
// a complicated spaghetti code in here, with dozens of nested 'ifs'
if (/* some expression */) {
} else if (/* some other expression */) {
// and so on... then suddenly:
if (/* some other nested expression */) {
// I forgot that I've allocated other memory at the beginning...
return A;
}
}
// some miserably written logic here and suddenly
if (D) delete D; return A;
// call to some other function with cryptical name without any
// kind of knowledge what happens with the resource:
FooTakesReferenceToPointer(&A);
// suddenly returning something completely different
// what should I free, A, D...?
return C;
}
I tried to write in comments what the problems are. Clearly, forget about exceptions. The spaghetti code is so bad that nobody can tell what the logic actually is. Therefore it is really, really easy to forget to free memory and that happens very, very frequently. Solution 1: Throw away and rewrite everything. Solution 2: Keep spaghetti as it is, replace all newed resources by smart pointers and make_shared or make_unique, let compiler yell. Of course, first write a test suite (which didn't exist before) to guarantee the same (often screwed) behaviour for all possible sets of inputs (which are not documented).
EDIT
As james said this is undefined behaviourso no promises
You could do something like this:
#include <vector>
class Base
{
public:
Base()
{
baseData = new char [1024];
}
~Base()
{
delete [] baseData;
}
private:
char* baseData;
};
class Derived : public Base
{
public:
Derived()
{
derivedData = new char[1024];
}
~Derived()
{
delete [] derivedData;
}
private:
char* derivedData;
};
int main()
{
std::vector<Base*> datablocks;
datablocks.push_back(new Base());
datablocks.push_back(new Derived());
for(unsigned int i = 0; i < datablocks.size(); ++i)
{
delete datablocks[i];
}
datablocks.clear();
return 0;
}
The data in the Derived class wont be removed here since we are calling delete on a Base* and the Base class does not declare a virtual destructor.
A lot examples could be given here. Just allocate some memory and do not free it.
A good example for this would be the following:
char* pBuffer = new char[ 1024 ]; // or something else, dynamically allocated
// do something here
// now suppose, calling f() throws
f();
// do some other things
delete[] pBuffer;
When f() throws, if the exception is not caught, delete[] will never be executed. Thus, memory leak.
This is one of the best examples why smart pointers should be used.
Another example would be - a function, returning pointer to dynamically allocated memory. The user, often, may forget to free this memory. Something like:
char
char* f()
{
return new char[ 1024 ];
}
//...
// in some other function
char* pSomething = f();
// do some stuff here and return
Imagine you're processing network data and create polymorphic "message objects" based on the data:
while (true)
{
char buf[1024];
size_t len = read_from_network(buf, 1024); // fictitious, for demonstration only
Message * p = Message::Parse(buf, len); // allocates new, dynamic, concrete object
engine.process(p);
}
The engine object may chose to store the object somewhere and use it again later, and if nobody takes care of deleting it, you have a perfect leak.
While the other answers give enough hints, some 'real world' memory leaks which I have seen in our applications.
I don't remember if this was found before or after the release, but, I guess that doesn't matter.
void f()
{
BYTE* b = NULL;
f = open a file;
while (!f.end())
{
int size = getNextRecordSize(f);
b = new BYTE;
readNextRecord(f,b);
process record;
}
delete b;
}
Bit hard to detect this. The reviewers might take it for granted that the memory is deleted properly by seeing the delete call. However, it deletes only the memory allocated for the last record. Rest is leaked.
class A
{
public:
BYTE* get()
{
allocate a new buffer, copy the someData buffer and return that.
The client is expected to delete it
};
private:
BYTE* someData;
};
void f()
{
A a;
B.initialize(a.get()); // It is so convenient to use the pointer. It is not obvious from the function name
// that the result of get has to be deleted.
}
One example I often run across in our code is in image understanding functions, where a temporary 8bit memory is allocated, and never released (yeah, I know, when you do a new, do a delete right afterwards...)
unsigned char* dataToBeUsed = new unsigned char[imgsize];
memcpy(dataToBeUsed, original, imgsize);
// use and process the data here
return value;
The allocated memory is never released -> memory leak. Windows will kill the memory when the application is exited completely, but before that within the application that memory is just lost -> leaked.
A memory leak occurs when the programmer has the memory leak of forgetting to free allocated memory :-)
linebuffer = new char[4096];
/* do things */
/* forget to free memory */
Normally, if you cause a memory leak and then exit the program, it is not harmful, since the operating system normally frees the resources allocated by the program. The problem arises when your application runs for a long period of time (for example, a service). If your program causes memory leaks, then you will run out system's memory, unless the operating system has mechanisms to avoid that; in such case, it will terminate your program.
So, be careful and eat fish: it's very good for memory :-)
To give you a real-world example, a bit of googling turned up this memory leak in 389 Directory Server (a RedHat Open Source product).
Just lose the pointer to dynamically allocated memory:
void foo()
{
int *arr = new int[100];
}
This is regarding deletion of this pointer for an object allocated on heap.Program is as follows,
class Sample{
private:
int m_value1;
int m_value2;
public:
Sample();
void setValues(int m_value1, int m_value2);
void display();
};
Sample::Sample(){
this->m_value1 = 0;
this->m_value2 = 0;
}
void Sample::setValues(int m_value1, int m_value2){
this->m_value1= m_value1;
this->m_value2 = m_value2;
display();
if(this != NULL)
{
cout <<"Deleting this pointer!"<<endl;
delete this;
cout <<"this->m_value1 is "<<this->m_value1<<endl;
cout <<"this->m_value2 is "<<this->m_value2<<endl;
}
}
void Sample::display(){
cout <<"Values are "<<this->m_value1<<" and "<<this->m_value2<<endl;
}
int main(){
Sample *obj1 = new Sample();;
obj1->setValues(4,6);
obj1->display();
getch();
}
OUTPUT:
Values are 4 and 6
Deleting this pointer!
this->m_value1 is 65535
this->m_value2 is 6
Values are 65535 and 6
Why does the value for m_value1 disappear whereas it stays for the other variable m_value2?
Accessing member variables after delete this is undefined behavior - anything can happen, including unexpected data being read, program crashing or anything else. The object has been destroyed and deallocated and you try to dereference an invalid pointer. Once delete this has happened - don't try to access the member variables, don't try t call member functions and don't do anything else (including comparing or casting) to this pointer.
Why does the value for m_value1 disappear whereas it stays for the other variable m_value2?
You are accessing memory after you deleted it. That means you are invoking undefined behavior.
So anything might happen, and your observation is as right or wrong as anything else.
What's likely going on is that the part of memory where m_value1 was stored is reused for something else, whilst the storage for m_value2 has not been used for something else (yet).
It's a matter of chance, probably the operator<< or whatever your do after deleting this allocates enough memory to overwrite the one and not the other.
But when you do something that shouldn't be done you should not rely on any particular consequences.
Dangerous and unpredictable outputs expected including system crash!
Do not delete location pointed to by this directly. its not a good programming practice. and don't use memory after deleting. and even if u have to put it inside an assert()
this != NULL // this will never be NULL if used properly.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Can a local variable's memory be accessed outside its scope?
Is there worrying thing to do a code such (getIDs() returns a pointer):
class Worker{
private:
int workerID;
int departID;
int supervisorID;
public:
Worker()
{
workerID=0;
departID=0;
supervisorID=0;
name="anonymous";
workerAddress="none";
}
void setIDs(int worker, int depart, int supervisor)
{
workerID=worker;
departID=depart;
supervisorID=supervisor;
}
int* getIDs()
{
int id[3];
id[0]=workerID;
id[1]=departID;
id[2]=supervisorID;
return id;
}
};
And then, use it such:
Worker obj;
obj.setIDs(11,22,33);
cout<<(*obj.getIDs())<<endl;
cout<<++(*obj.getIDs())<<endl;
cout<<++(++(*obj.getIDs()))<<endl;
I am wondering about that because the compiler shows:
Warning 1 warning C4172: returning address of local variable or
temporary
Your int id[3] is allocated on a stack and gets destroyed when your int* getIDs() returns.
You're return a pointer to a variable that gets destroyed immediately after getIDs() returns. The pointer then becomes dangling and is practically useless as doing anyting with it is undefined behaviour.
Suppose you defined your class like this:
class Worker{
private:
int IDs[3];
public
// ...
int* getIDs() { return IDs; }
};
This partially solves your problem, as the pointer remains valid as long the Worker object is in scope, but it's still bad practice. Example:
int* ptr;
while (true) {
Worker obj;
obj.setIDs(11,22,33);
ptr = obj.getIDs();
cout << *ptr; // ok, obj is still alive.
break;
} // obj gets destroyed here
cout << *ptr; // NOT ok, dereferencing a dangling pointer
A better way of solving this is to implement your custom operator << for your class. Something like this:
class Worker {
private:
int workerID;
int departID;
int supervisorID;
public:
// ...
friend ostream& operator<<(ostream& out, Worker w);
};
ostream& operator<<(ostream& out, const Worker& w)
{
out << w.workerID << "\n" << w.departID << "\n" << w.supervisorID;
return out;
}
Even if this would work, it wouldn't be good practice to do it this way in c++ unless there is some profound reason why you want pointers to int. Raw c-syle arrays are more difficult to handle than, for instance, std::vectors, so use those, like
std::vector<int> getIDs(){
std::vector<int> id(3);
id[0]=workerID; id[1]=departID; id[2]=supervisorID;
return id;
}
If you're worried about the overhead: this is likely to be optimized away completely by modern compilers.
A local (also caled automatic) variable is destroyed once you leave the function where it is defined. So your pointer will point to this destroyed location, and of course referencing such a location outside the function is incorect and will cause undefined behaviour.
The basic problem here is that when you enter a function call, you get a new frame on your stack (where all your local variables will be kept). Anything that is not dynamically allocated (using new/malloc) in your function will exist in that stack frame, and it gets destroyed when your function returns.
Your function returns a pointer to the start of your 3-element-array which you declared in that stack frame that will go away. So, this is undefined behavior.
While you may get "lucky/unlucky" and still have your data around where the pointer points when you use it, you may also have the opposite happen with this code. Since the space is given up when the stack frame is destroyed, it can be reused - so another part of your code could likely use the memory location where your three elements in that array is stored, which would mean they would have completely different values by the time you dereferenced that pointer.
If you're lucky, your program would just seg-fault/crash so you knew you made a mistake.
Redesign your function to return a structure of 3 ints, a vector, or at the very least (and I don't recommend this), dynamically allocate the array contents with new so it persists after the function call (but you better delete it later or the gremlins will come and get you...).
Edit: My apologies, I completely misread the question. Shouldn't be answering StackOverflow before my coffee.
When you want to return an array, or a pointer rather, there are two routes.
One route: new
int* n = new int[3];
n[0] = 0;
// etc..
return n;
Since n is now a heap object, it is up to YOU to delete it later, if you don't delete it, eventually it will cause memory leaks.
Now, route two is a somewhat easier method I find, but it's kind of riskier. It is where you pass an array in and copy the values in.
void copyIDs(int arr[3] /* or int* arr */)
{
arr[0] = workerID;
/* etc */
}
Now your array is populated, and there was no heap allocation, so no problem.
Edit: Returning a local variable as an address is bad. Why?
Given the function:
int* foo() {
int x = 5;
return &x; // Returns the address (in memory) of x
} // At this point, however, x is popped off the stack, so its address is undefined
// (Garbage)
// So here's our code calling it
int *x = foo(); // points to the garbage memory, might still contain the values we need
// But what if I go ahead and do this?
int bar[100]; // Pushed onto the stack
bool flag = true; // Pushed onto the stack
std::cout << *x << '\n'; // Is this guaranteed to be the value we expect?
Overall, it is too risky. Don't do it.
I would like to ask if I's correct the following :
MyClass *obj = new MyClass();//allocate memory
obj.Variab="HELLO";
obj=NULL;
delete obj; //free memory
Is the memory allocated for obj deleted after the last two sentences? Appreciate.THX
I would like to mention that I am working in c++ /Ubuntu. G++ is the compiler
EDIT:
What if I have?
int i=0;
list<string>l;
while (i<100)
{
MyClass *obj = new MyClass();//allocate memory
obj->Variab="HELLO";
//add the obj.valie in a list
l.push_back(obj);
i=i+1;
delete obj; //free memory
}
it is ok?
no, you should use delete before assigning to NULL
delete obj; //free memory
obj=NULL;
this is becasue the actual parameter to delete is the address of the allocated memory, but if you assign NULL before delete is used, you are actually passing NULL to delete, and nothing will happen, and you will get yourself a memory leak.
your edit question:
this code will not compile, as obj is not defined outside the while scope, in any case, also, l is a list<string> and you are trying to insert MyClass* types,this will result in another compilation error. also, you should use obj->Variab and not obj.Variab, since obj is a pointer.
EDIT to EDIT:
well, you still got a compilation error, since obj is not defined when you are trying to delete it. try this:
#include <iostream>
#include <list>
using namespace std;
class MyClass {
public:
string Variab;
};
void myfunction (const string& s) {
cout << " " << s;
}
int main()
{
int i=0;
list<string>l;
while (i<100) {
MyClass *obj = new MyClass();//allocate memory
obj->Variab="HELLO";
l.push_back(obj->Variab);
i=i+1;
delete obj; //free memory
}
for_each (l.begin(), l.end(), myfunction);
}
This not correct:
obj = NULL; // don't do that!
delete obj;
When you assign NULL to obj, you're losing the address it contained before, leaking the memory. When you then delete obj, you are deleting NULL, which is well-defined - as doing nothing.
As others have said,
delete obj;
obj = NULL;
is the common pattern to do that.
However, I consider it an anti-pattern.
Whenever you are tempted to assign NULL to a pointer after deleting its content, ask yourself: Why is this pointer still in scope? Are you sure you still need it?
It's much better to simply let a pointer fall out of scope once it's done.
Whenever you are doing
resource r = acquire();
use(r);
free(r);
(with memory/dynamically allocated objects being the most common resource), alarm bells should go off. What if use(r) fails with an exception?
Never use naked, dumb pointers. Better read about RAII and smart pointers.
This would leak, delete will not clean up what you allocated with new. Change the order:
delete obj;
obj = NULL; // I would avoid this.
Setting obj to null does not free the memory you allocated. The memory becomes no longer assigned to a variable but is still reserved, and results in a memory leak. Calling delete on a null pointer will have no effect. After the memory has been freed, the pointer becomes invalid and it is good practice to assign it to null. You need to switch the order of the last 2 statements:
delete obj; //free memory first
obj=NULL; //Set pointer to null for safety
You have to delete the very same address as was returned by new - so you have to first delete, then set to null.
Setting pointer to null doesn't affect allocation - you just overwrite the address stored in the pointer and can't access the object anymore (which implies you can't delete the object and have it leaked).
I am trying to define a class in the global scope which contains some dynamically-allocated arrays. When the class' constructor is called, the program does not have access to user-defined parameters read through a parameter file (i.e. the number of years in a simulation) thus it cannot allocate memory to the proper size. My idea was to allocate memory within a private function in the class, and then deallocate it using the destructor. Some example code:
class Simulation{
private:
int initial_call; //a flag used to initialize memory
double *TransferTracker;
public:
Simulation();
~Simulation();
void calc();
};
Simulation simulator; //global instance of Simulation
Simulation::Simulation()
{
initial_call = 1;
}
Simulation::~Simulation()
{
//when calling the destructor, though, the address is
//0xcccccccc and the following attempt to delete produces
//the compiler error.
delete [] TransferTracker; //see error
}
void Simulation::calc()
{
for (int i = 0; i < num_its; i++)
{
if (initial_call)
{
TransferTracker = new double [5];
//The address assigned is, for example, 0x004ce3e0
initial_call = 0;
}
}
//even if this calc function is called multiple times, I see
//that the address is still 0x004ce3e0.
}
The error I receive from the above code fragment is:
Unhandled exception at 0x5d4e57aa (msvcr100d.dll) in LRGV_SAMPLER.exe: 0xC0000005: Access
violation reading location 0xccccccc0.
This error makes sense because I checked the memory address of TransferTracker when entering the destructor. My question is, why do we lose the address when entering the destructor? It probably has something to do with the fact that simulator is global; this paradigm seems to work fine if the class was not global. I am new to object-oriented programming so any help is appreciated!
EDIT: This was basically a blunder on my part and was helped by the answers. Two problems occurred: (1) the pointers were never set to NULL, thus creating confusion on trying to delete unallocated pointers. (2) There were actually two instances of the class in my scope, which was a mistake on my part. In the final code, there will only ever be one instance. Thanks everyone!
Initialize the pointer to NULL (0)
Simulation::Simulation() : TransferTracker(NULL)
{
initial_call = 1;
}
Simulation::~Simulation()
{
//when calling the destructor, though, the address is
//0xcccccccc and the following attempt to delete produces
//the compiler error.
if(TransferTracker) delete [] TransferTracker; //see error
TransferTracker = NULL;
}
That way you can check wether or not it has been initialised when you want to delete it. It's best practice, so do it always, not only at construction
EDIT:
void Simulation::calc()
{
for (int i = 0; i < num_its; i++)
{
if (initial_call)
{
if(TransferTracker) delete [] TransferTracker;
TransferTracker = new double [5];
initial_call = 0;
}
}
}
You have to initialize the value of the instance variable TransferTracker to 0 in the constructor. The problem you're having is the destruction of the Simulation class without actually having assigned dynamic memory to TransferTracker.
Calling delete[] in the destructor with a null pointer is safe. The problem is that if you don't give a value to TransferTracker, it may have any undefined value, that will cause trouble trying to deallocate with delete[].
EDIT:
As per your edit, how do you assure that there is only one instance of the Simulation class? This has to do with if you include several .o files in your build, etc.
I suspect the cause is that your destructor is getting called when you haven't invoked the calc() function, therefore the memory hasn't been allocated yet.
You want to put in place a "guard" that will make sure that you've already allocated the memory before attempting to deallocate the memory for TransferTracker.