This question already has answers here:
What does delete command really do for memory, for pointers in C++? [duplicate]
(6 answers)
Closed 6 years ago.
I am pretty new to this concept and I am confused that if a dangling pointer is a pointer which points to a memory location which points to memory which has been freed or deleted then in this case why it is still able to call the function test()
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
using namespace std;
class MyClass{
public:
void test(){
cout<< "just checking"<<endl;
}
};
int main(int argc, char **argv)
{
MyClass *p ( new MyClass());;
MyClass *q = p;
delete p;
q->test();
p = NULL;
q->test();
return 0;
}
Any help would be appreciated.
Delete runs the destructor of the class, and marks the memory as freed. If the destructor doesn't do anything too destructive, and if the memory has not yet been reallocated for some other purpose, then the object turns into what is basically a zombie: it looks vaguely like one of the living, but is really preparing to eat your brain.
Don't let your brain get eaten.
Related
Following is my code snippet. I am trying to write generic function to check whether pointer is valid and deleting it.
#include <windows.h>
#include <vector>
#include <map>
#include <string>
using namespace std;
struct testStruct
{
int nVal;
_TCHAR tcVal[256];
testStruct()
{
wmemset(tcVal, 0, _countof(tcVal));
}
};
void deletePointer(void *obj)
{
if (obj)
{
delete obj;
obj = NULL;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
testStruct *obj = new testStruct;
wstring *strVal = new wstring();
vector<wstring> *vecVal = new vector<wstring>;
map<wstring,wstring> *mapVal = new map<wstring, wstring>;
//My business logic goes here.
//Finally after all business logic, clearing allocated memory.
deletePointer(obj);
deletePointer(strVal);
deletePointer(vecVal);
deletePointer(mapVal);
return 0;
}
While I am not facing any compilation or runtime error, just wanted to confirm, if this is the right way to check and delete multiple points. I don't want to check individual pointer whether it is valid or not before deleting. So calling generic function.
Thanks for your suggestions in advance.
Compilation and runtime errors are not present. Just need confirmation, if this is right way or is there a better way to do this.
No, it's both incorrect and unnecessary
If your compiler doesn't report error on this code, crank up warnings: https://godbolt.org/z/7ranoEnMa. Deleting a void* is Undefined Behaviour, you cannot predict what will be the result. If it's currently not crashing, it will likely crash at some random other use when you will least expect it.
It's unnecessary, because it's perfectly fine to delete nullptr; and your function only checks against that. If you wanted to check if the pointer is actually valid like Nathan Pierson suggests in comment (and you don't assign nullptr to them consistently), that's not possible. You are responsible for your memory management, no if can help if you don't do that correctly throughout the program.
And it's also not necessary, because memory management is already done for you. Containers shouldn't be ever allocated on the heap. Simply do
wstring strVal;
vector<wstring> vecVal;
map<wstring,wstring> mapVal;
And drop the pointers. C++ containers do all the magic by themselves and are generally small by themselves (sizeof(std::vector) is usually 3*sizeof(void*)).
Assuming you really need testStruct on the heap rather than in automatic storage, you should use a smart pointer:
std::unique_ptr<testStruct> obj = std::make_unique<testStruct>();
There, it's created, allocated on the heap and will be automatically deleted when obj ends its scope. You don't have to worry about deleteing anything anymore.
If you really want to have a function that deletes objects manually, it should look like this:
template <typename T>
void deletePointer(T*& obj)
{
delete obj;
obj = nullptr;
}
It keeps the type of the pointer to be deleted and updates passed pointer with nullptr, so it won't be invalid later on.
This question already has answers here:
Memory consumption after new then delete
(3 answers)
Closed 3 years ago.
I declare and assign vector pointer with shared pointer of class that has a big-size array pointer.
From deleting the vector pointer, I expect to free the memory from the big array. My question is that why the memory is NOT deallocated at the right moment after 'delete vec' before 'return 0'. From debugging mode, you can see it in the window task manager. Please let me know why 'delete vec' does not work as I expected.
class test
{
public:
test() { A = new double[500000000]; }
~test() { delete[] A; }
double *A;
};
int main()
{
vector<shared_ptr<test>> *vec =new vector<shared_ptr<test>>();
vec->push_back(shared_ptr<test>(new test()));
vec->push_back(shared_ptr<test>(new test()));
vec->push_back(shared_ptr<test>(new test()));
delete vec;
return 0;
}
I tested your code and there is no problem when deleting ptr.
This question already has answers here:
C++ delete - It deletes my objects but I can still access the data?
(13 answers)
Closed 4 years ago.
The pointer *sbi memory is freed using the delete operator but still the code executes correctly without providing garbage value. is the constructor re-initializing or is the a fault in code/
#include <iostream>
using namespace std;
class bank
{
private:
int balance;
public:
bank();
void dep(int x);
void with();
~bank();
};
int main()
{
bank *sbi;
sbi = new bank;
sbi->dep(50000);
delete sbi; /// problem is in this section of code
sbi->with();
return 0;
}
bank :: bank()
{
balance=0;
}
void bank::dep(int x)
{
balance=x;
}
void bank::with()
{
cout<<balance<<endl;
}
bank::~bank()
{
cout<<"destroy"<<endl;
}
Freeing a memory location does not automatically overwrite it with garbage. By coincidence, that value stored in balance is still the same.
People, I am new to all this programming talk. Up until now it was quite easy to find answers by googling them but right here I have big trouble expressing what I want to ask, let me try: Erasing a vector calls the destructor before freeing the memory, right? Now how does a struct-vector react, if it is destructed? One does not define a destructor for these things, but is it correct to assume that if a struct is "destructed" each of its members' destructors will be called as well?
Let me give you an example:
#include <string>
#include <vector>
struct ding_t {
std::string dang;
} foo;
strung boom_t {
vector <ding_t> chuck;
} bar;
int main () {
vector <boom_t> tom;
tom.resize(10);
tom[4].chuck.resize(5);
tom[4].chuck[3].dang = "jerry";
tom.erase();
return 0;
}
in this case, will the memory allocated by
tom[4].chuck.resize(5);
be freed as well? Sorry for my vocabulary, but at this moment I am trying to move from pointers to the more sophisticated cpp language equivalent of vectors. I hope I got my point across. Thanks in advance guys and please just redirect me if this has already been asked, as I've said, I don't know how to circumscribe this question.
Yes, the memory will be freed automatically.
When a vector is destructed it will call the destructor of all the elements it contains. You didn't define a destructor for your struct so the compiler will provide a default one for you (that does nothing).
However if your vector contains pointers to objects it will be your responsibility to call the destructor on the objects before destructing the vector (because the vector will call the destructor of the pointers, not the pointed objects), if you have no other way to access them later.
See http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.11 for the answer to your question and the entire article for a very good treatment of destructors in C++.
As to your second question: yes, the memory allocated by tom[4].chuck.resize(5); will get freed as well, since it is the vector's responsibility to manage its own memory allocations (which is the case for the "resize()" call.)
Answer: Since you are not allocating the Object dynamically with the new operator, you dont have to deallocate them manually.
It's done automatically for you.
Ok. Back to your code :)
If you want to erase the 6th element then use tom.erase (tom.begin()+5) .
And if you want to erase all elements then use tom.erase (tom.begin(),tom.end() ) .
To erase the first 3 elements use tom.erase (tom.begin(),tom.begin()+3).
#include <string>
#include <vector>
using namespace std;
struct ding_t
{
std::string dang;
} foo;
struct boom_t {
std::vector <ding_t> chuck;
} bar;
int main () {
vector <boom_t> tom;
tom.resize(10);
tom[4].chuck.resize(5);
tom[4].chuck[3].dang = "jerry";
//error C2661: 'erase' : no overloaded function takes 0 parameters
//tom.erase( );
// erase the 6th element
tom.erase (tom.begin()+5);
// erase the first 3 elements:
//tom.erase (tom.begin(),tom.begin()+3);
// erase everything:
//tom.erase (tom.begin(),tom.end() );
return 0;
}
Okay, I've done this little check, just to make sure. (Why didn't I think of this earlier... was quite late yesterday... ) The initial code was badly written and didn't work, apologies for that.
This:
#include <string>
#include <vector>
struct ding_t {
std::string dang;
} foo;
struct boom_t {
std::vector <ding_t> chuck;
} bar;
int main () {
std::vector <boom_t> tom;
while (true) {
tom.resize(10);
tom[4].chuck.resize(5);
tom[4].chuck[3].dang = "jerry";
tom.erase( tom.begin(), tom.end() );
}
return 0;
}
causes no memory leak, the used memory is stable.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is it safe to delete a void pointer?
Will the following code cause memory leak?
void *ptr = new long [10];
delete[] ptr; // note: ptr is a void*
[EDIT]
The code above will generate a warning message during compiling to specify it "undefined".
I ask this cause I'm wondering how does C++ handle memory ranges when delete[] is called.
I should change my question to make it more specified.
Will the following code cause memory leak?
char *ptr = (char *)(new long [10]);
delete[] ptr; // note: ptr is a char*
No. Leaving delete[] out will cause a leak. BTW, it should be long* ptr. I don't think the delete[] will even compile with a void* argument.
I tried the following program (slight modification of this example):
#include <iostream>
#include <new>
using namespace std;
struct myclass {
myclass() {cout <<"myclass constructed\n";}
~myclass() {cout <<"myclass destroyed\n";}
};
int main () {
void * pt = new myclass[3];
delete[] pt;
return 0;
}
using g++ and got the following compilation warning:
leaky.cpp: In function ‘int main()’:
leaky.cpp:13: warning: deleting ‘void*’ is undefined
And when you run it...fail! The process dies (invalid pointer) when you attempt to delete that pointer.