Must I free structure memory after using it? I have sample code:
struct aa
{
int a;
char * b ;
aa()
{
a=0;
b= new char[255];
}
} ;
aa *ss = new aa[3];
void fill()
{
aa * ssss = new aa;
aa * sss = new aa;
sss->a=10;
ss[0] = *sss;
cout<<ss[0].a<<"\n";
ss[1] = *sss;
cout<<ss[1].a<<"\n";
cout<<ssss[1].a<<"\n";
}
int _tmain(int argc, _TCHAR* argv[])
{
fill();
delete(ss);
}
Must I do delete(ssss) at the end of fill?
Must I delete ss array of structure at the end of main?
Must I create destruct or to structure ss that frees *b memory?
What about classes is it the same logic?
Must I do delete(ssss) at the end of fill?
Yes, you must delete anything created with new. However, there's no need to use new here, just make it automatic:
void fill() {
aa ssss; // automatically destroyed on exit from the function
}
Must I delete ss array of structure at the end of main?
Yes, but it is an array, so must be deleted as an array:
delete [] ss;
^^
But again, there's no reason for this to be dynamically allocated:
aa ss[3]; // automatically destroyed on exit from the program
Must I create destruct or to structure ss that frees *b memory?
If you really want to use a raw pointer to manage the dynamic array, then yes. You will also need to think about a copy constructor and copy-assignment operator (per the Rule of Three) to make the class safe to use. Alternatively, use a smart pointer or container to manage the memory for you:
struct aa
{
int a;
std::vector<char> b ;
aa() : a(0), b(255) {}
} ;
What about classes is it the same logic?
Yes, the rule is always the same: anything created with new must be destroyed with delete. Managing objects is much easier if you avoid dynamic allocation where possible, and use smart pointers, containers and other RAII classes when you really do need it.
If you use new, you must use delete to avoid a memory leak. If you declare a variable on stack, it will be freed automatically when you exit the scope.
void something();
{
aa b = new aa();
// Do something
delete b; // You must use delete
}
void something();
{
aa b();
// Do something
// You don't have to use delete
}
In your specific case, it is not strictly necessary to use delete, because the program is going to terminate anyway and all the assigned memory will be freed by the OS.
It is still a good practice to do so, so as to be consistent (though there are some specific cases where you DON'T want to do this because freeing a lot of complex objects can take some time thus slowing down the program termination).
Anyhow, using naked pointers is not such a good idea in C++ since there are many so-called smart pointers (such as shared_ptr and unique_ptr) that take care of calling the destructor and freeing the memory after they run out of scope.
PS: In your code, you will have a memory leak, because the aa structure uses new inside the constructor and does not call delete in destructor.
YES
Please, please, please free your memory. I won't go into detail here, but take a look at this answer:
Can a memory block allocated by using operator new/malloc persist beyond end of program execution?
Rule of thumb in C/C++:
Allocated with new? free the memory with delete
Allocated with malloc, calloc, realloc? free the memory with free(void*)
Related
I use extra brackets in my code. I thought when the destructor should be called after the local variable scope is ended but it doesn't work like this:
class TestClass {
public:
TestClass() {
printf( "TestClass()\n" );
}
~TestClass() {
printf( "~TestClass()\n" );
}
};
int main() {
int a, b, c;
{
TestClass *test = new TestClass();
}
}
It outputs:
TestClass()
So it doesn't call the destructor of the TestClass but why? If I call it manually (delete test) it calls the destructor, right. But why it doesn't call the destructor in the first case?
TestClass *test = new TestClass();
You using new which creates a dynamically allocated object (most likely placed on the heap). This type of resource needs to be manually managed by you. By managing, you should use delete on it after you have done using it.
{
TestClass *test = new TestClass();
// do something
delete test;
}
But for the most of your purposes and intents, you just have to use automatic-storage objects, which frees you the hassle of having to manually manage the object. It would also most likely to have better performance especially in short-lived objects. You should always prefer to use them unless you have a really good reason not to do so.
{
TestClass test;
// do something
}
However, if you need the semantics of dynamically allocated objects or that of pointers, it will always be better to use some mechanism to encapsulate the deletion/freeing of the object/resource for you, which also provides you additional safety especially when you are using exceptions and conditional branches. In your case, it would be better if you use std::unique_ptr.
{
std::unique_ptr<TestClass> test(new TestClass());
// auto test = std::make_unique<TestClass>(); in C++14
// do something (maybe you want to pass ownership of the pointer)
}
The following is a relevant link to help you decide whether to use automatic storage objects or dynamically allocated objects: Why should C++ programmers minimize use of 'new'?
Because you have a pointer to a dynamically allocated object. Only the pointer goes out of scope, not the object it points to. You have to call delete on the pointer in order for the pointee's destructor to get called.
Try with an automatic storage object instead:
{
TestClass test;
}
Here, the destructor will be called on exiting the scope.
The use of raw pointers to dynamically allocated objects in C++ is discouraged because it can easily lead to resource leaks like the one shown in your code example. If pointers to dynamically allocated objects are really needed, it is wise to handle them with a smart pointer, rather than to attempt to manually deal with their destruction.
This answer is good enough but just to add some more.
I see you have been coded with Java. In C++ to create variable/object in stack keyword new is not needed. Actually when you use keyword new your object is creating in heap and it doesn't destroys after leaving scope. To destroy it you need to call delete in your case delete test;
In such a structure as yours, after leaving scope you just lose pointer what points into object, so after leaving scope you cannot free memory and call destructor, but eventually OS call destructor just after exit() instruction is executed.
To sum up C++ != Java
Coverity reports leaks for the following code. I would like some help understanding the errors and to re-write this code to be error free.
( The errors are annotated as comments in the code below )
int main()
{
...
B* b = ...
// (1) Coverity: Storage is returned from
// allocation function operator new
// (2) Coverity: Assigning ...
A* a = new A();
// (3) Coverity: noescape: Resource a is not freed
// or pointed-to in add_a_to_b
b->add_a_to_b( *a );
...
// (4) Coverity: Resource leak: Variable a going out
// of scope leaks the storage it points to.
}
class B {
public:
std::vector<A> a_vector;
void add_a_to_b( const A& a )
{
a_vector.push_back( a );
}
-- EDIT ---
I had a particular question about the B::add_a_to_b function, and this reflects my incomplete understanding of references perhaps: Does a_vector store a reference to A or does it create a copy of the object passed to add_a_to_b?
You have a memory leak because you called new and you don't call delete. Furthermore, there is no reason for you to call new or allocate dynamically. You can simply allocate a automatically. The same applies to b.
B b;
A a;
...
b.add_a_to_b(a); // b stores a copy of `a`.
Well. You allocate memory for a, but you never use delete.
For every new there must be one delete.
delete a; // Do this when you don't need a anymore.
You can also do this - a = nullptr; to avoid a dangling pointer.
Edit:
You should learn how to use smart pointers. They're fairly easy to learn and you wouldnt have to worry about using new and delete, it'll take care of the delete.
Read this - Wiki & What is a smart pointer and when should I use one?
I use extra brackets in my code. I thought when the destructor should be called after the local variable scope is ended but it doesn't work like this:
class TestClass {
public:
TestClass() {
printf( "TestClass()\n" );
}
~TestClass() {
printf( "~TestClass()\n" );
}
};
int main() {
int a, b, c;
{
TestClass *test = new TestClass();
}
}
It outputs:
TestClass()
So it doesn't call the destructor of the TestClass but why? If I call it manually (delete test) it calls the destructor, right. But why it doesn't call the destructor in the first case?
TestClass *test = new TestClass();
You using new which creates a dynamically allocated object (most likely placed on the heap). This type of resource needs to be manually managed by you. By managing, you should use delete on it after you have done using it.
{
TestClass *test = new TestClass();
// do something
delete test;
}
But for the most of your purposes and intents, you just have to use automatic-storage objects, which frees you the hassle of having to manually manage the object. It would also most likely to have better performance especially in short-lived objects. You should always prefer to use them unless you have a really good reason not to do so.
{
TestClass test;
// do something
}
However, if you need the semantics of dynamically allocated objects or that of pointers, it will always be better to use some mechanism to encapsulate the deletion/freeing of the object/resource for you, which also provides you additional safety especially when you are using exceptions and conditional branches. In your case, it would be better if you use std::unique_ptr.
{
std::unique_ptr<TestClass> test(new TestClass());
// auto test = std::make_unique<TestClass>(); in C++14
// do something (maybe you want to pass ownership of the pointer)
}
The following is a relevant link to help you decide whether to use automatic storage objects or dynamically allocated objects: Why should C++ programmers minimize use of 'new'?
Because you have a pointer to a dynamically allocated object. Only the pointer goes out of scope, not the object it points to. You have to call delete on the pointer in order for the pointee's destructor to get called.
Try with an automatic storage object instead:
{
TestClass test;
}
Here, the destructor will be called on exiting the scope.
The use of raw pointers to dynamically allocated objects in C++ is discouraged because it can easily lead to resource leaks like the one shown in your code example. If pointers to dynamically allocated objects are really needed, it is wise to handle them with a smart pointer, rather than to attempt to manually deal with their destruction.
This answer is good enough but just to add some more.
I see you have been coded with Java. In C++ to create variable/object in stack keyword new is not needed. Actually when you use keyword new your object is creating in heap and it doesn't destroys after leaving scope. To destroy it you need to call delete in your case delete test;
In such a structure as yours, after leaving scope you just lose pointer what points into object, so after leaving scope you cannot free memory and call destructor, but eventually OS call destructor just after exit() instruction is executed.
To sum up C++ != Java
I'm new to C/C++ and developing a C++ application. There I have a problem with new and malloc. My application is bit complex and there are some C structs as well. At some point, I wanted to allocate new memory for Class of type MyData (which contains a deque) and later I assigned that pointer to a pointer in a C struct. Smaller version of my code is as follows.
#include <deque>
class MyData
{
public:
MyData(){};
~MyData() {};
std::deque<int>& GetDequeMyDataSet() {return deque_MyDataSet; };
private:
std::deque<int> deque_MyDataSet;//contains ohlc data for the symbol
};
int _tmain(int argc, _TCHAR* argv[])
{
MyData* pMyData = new MyData();
MyData* p_Data = (MyData*)malloc(sizeof(MyData*));
p_Data = pMyData;
p_Data->GetDequeMyDataSet().push_back(10);
p_Data->GetDequeMyDataSet().push_back(11);
//.... Several other push back and operations releated to this deque goes here.
delete pMyData;// At the end I free both memories.
free(p_Data);
return 0;
}
After allocating memory for both pointers I used GetDequeMyDataSet() method on malloc pointer (p_Data). My problem is whether it is ok to push_back items to the deque on this malloc pointer, as I have allocated memory for the pointer only? Can malloc handle dynamic memory allocation for deque?
Here's your situation in simplified terms:
void * p = malloc(1);
void * q = malloc(1);
q = p;
free(q);
free(p);
Can you spot the problem?
No point in using deque if you mostly push_back elements. It's slower in pushing back elements and faster in push_front compared to vectors insert. Also using malloc is just asking for problems. Same goes for new, use std::shared_ptr or std::unique_ptr if you really need to allocate your class object dynamically. They will take care of memory deallocation for you.
#include <vector>
class MyData
{
public:
MyData() {};
~MyData() {};
std::vector<int>& GetMyDataSet() { return m_myDataSet; }
private:
std::vector<int> m_myDataSet;
};
int _tmain(int argc, _TCHAR* argv[])
{
MyData myData;
myData.GetMyDataSet().push_back(10);
//or dynamically
auto pMyData = std::make_shared<MyData>();
pMyData->GetMyDataSet().push_back(10);
return 0;
}
The difference between malloc and new is that the first does not call the class's constructor while the later does. The constructor in turn calls the constructors of the member variables as is the case with deque_MyDataSet in this case. So what you do will not call the constructor of the deque.
Always use new in C++ to avoid problems later on. And to ensure everything is initialized correctly.
Mixing malloc() and new is a bad idea. Also, what is a "C class"?
Anyway, this:
MyData* p_Data = (MyData*)malloc(sizeof(MyData*));
is flat out wrong, you're not allocating the correct amount of memory. You mean:
MyData* p_Data = (MyData *) malloc(sizeof *p_Data);
since you must have the actual size of the MyData structure being pointed at. Your code allocated only enough room for the the pointer, which is not what you mean.
Note that the cast is required in C++, but is bad practice in C.
My problem is whether it is ok to push_back items to deque on this malloc pointer as it has allocated memory for pointer only?
Normally, it is ok to push_back items into an object no matter how it was initialized (allocated dynamically or on the stack). In this case though, p_Data was allocated, but not initialized at all.
To see this, you need to understand the difference between malloc and new:
malloc is the C function that allocates a block of memory and returns a (void) pointer to it. The reason it exists in C++ is because C++ was initially compatible with C and able to use it's libraries (and nowadays it is required for backwards compatibility.
new is the C++ operator that allocates a block of memory, interprets it as an object, and calls the constructor for that object transparently. The two functions are not interchangeable.
When you allocate memory for an object, always use new. malloc will not call the constructor of your object (nor will free call the destructor of your object).
Equivalent code:
class MyData { /* same as in your question */ };
// 1: normal C++ dynamic object allocation
MyData* pMyData = new MyData();
// 2: allocate through malloc and call constructor through placement new
void* block = (MyData*)malloc(sizeof(MyData)); // allocate sizeof(MyData) bytes
MyData* pMyData = new(block) MyData(); // call constructor on block memory
This means that if you use malloc and free, your objects are not initialized, even though normally (intuitively) you'd expect them to be.
TL:DR: Never use malloc and free in C++.
After allocating for memory both pointers I used GetDequeMyDataSet() method on malloc pointer(p_Data)
That shouldn't have worked. The malloc'd pointer should not be initialized (allocated yes, initialized no).
On top of that, since you assign p_Data = pMyData;, your call to free will attempt to release memory already assigned by the delete statements (since both point to the same address).
That should be seen as an access violation error.
In C++ there is often no need to allocate things dynamically. You just create a new object when you need one:
int _tmain(int argc, _TCHAR* argv[])
{
MyData myData; // No pointers, no new
MyData* p_Data = &myData; // Create a pointer to myData, if you need one
p_Data->GetDequeMyDataSet().push_back(10);
p_Data->GetDequeMyDataSet().push_back(11);
//.... Several other push back and operations releated to this deque goes here.
// Nothing to delete or free here
return 0;
}
I had made a header file with a class named cmysqldb with a lot of pointers.
My problem is now this:
How could i create a destructor that will delete the pointers that may cause potential memory leak?
here is the header code:
#ifndef CMSYQLDB_H
#define CMSYQLDB_H
#include <QMultiMap>
#include <QStringList>
#include "mysql.h"
class cmysqldb
{
public:
cmysqldb::~cmysqldb()
{
const char *text,
MYSQL *connection,
MYSQL_RES *result,
MYSQL_RES *fresult,
MYSQL_FIELD *mfield
}
int query_state;
int numfields;
MYSQL mysql;
MYSQL_ROW row;
MYSQL_ROW fieldrow;
....
};
#endif // CMSYQLDB_H
is this what you mean???
Resources acquired through new should be deallocated using delete and with new[] should be with delete[]. As simple as that to avoid memory leaks. Could be more helpful if you post more specific code.
Destructor bears the same name of the class, except that it has a ~ symbol before it.
cmysqldb :: ~cmysqldb()
{
// deallocate the resources with the above mentioned rule
}
class foo
{
int var ;
int *ptr ;
public:
foo()
{
ptr = new int ;
}
~foo()
{
delete ptr ;
}
};
void bar()
{
foo obj ;
// .....
} // <-- obj goes out of scope and it's destructor is called at this point.
foo class has two member variables var, ptr of type int, int* respectively. So, bytes required to hold an integer in var and pointer(ptr) that can point to an integer's address is automatically allocated. These resources are not allocated by us. So, it's not our responsibility to deallocates these resources. So far so good.
ptr = new int ;
new int acquires resources from the free store that can hold an int and it's address is returned which ptr holds. Now, this acquisition of resource from free store is because of the new operation defined by the user. So, it's the job of the user to return the resources back to the free store. So, the statement in the destructor -
delete ptr ;
Get a book from The Definitive C++ Book Guide and List which can even explain better. Also follow #Michael advice of using smart pointers which manages resources automatically.
In order to delete the pointers, you will need to store them somewhere. It is unclear where you do this (you don't have fields for all the pointer parameters accepted by the constructor), so I won't be able to give you exactly the code to do this, but I will lay out how you can go about doing this.....
To declare the destructor, add the following to your class declaration:
~cmysqldb();
Note that if your class will have any virtual methods, you should instead declare it as:
virtual ~cmysqldb();
And in your source file add:
cmysqldb::~cmysqldb()
{
// contents of your destructor goes here.
}
Now, how exactly you free your resources depends on how they were allocated. If you used some library-specific create function and there is a library-specific free function, then use that. If it was allocated using malloc, then use free; if it was allocated with new, use delete; if it was allocated using new[], then use delete[]. Also, you should use smart pointer classes such as boost::scoped_ptr (std::unique_ptr) or boost::shared_ptr (std::shared_ptr), wherever possible to avoid explicitly managing these resources via new/delete in your constructors / destructors.
One last, very important point... whenever you have a function that accepts a pointer, it is very important that you document the ownership semantics. Is it owned by the caller? Is ownership transferred? Etc.
A memory leak occurs when you acquire dynamic memory using new or new[] & do not deallocate the memory using delete or delete[]`.
Your constructor declaration is of the type:
cmysqldb(const char *text, MYSQL *connection, MYSQL_RES *result,
MYSQL_RES *fresult, MYSQL_FIELD *mfield);
You should keep a track of whatever dynamic memory allocations you are doing in the constructor with new and new[]and you should deallocate all of them with a corresponding delete or delete[].
The best thing to do would be to use smart pointers to store all the pointers to related objects. C++ will automatically call destructors of all sub-objects when the parent object is destroyed.
And if your parent object fails partly constructed, its destructor won't be called. So any pointers already allocated would leak if you design things to be freed in the destructor. However, subobjects destructors get run if the subobject was allocated, so by using smart pointers this partly allocated case is taken care of for you.
For more information, look up RAII (Resource Acquisition Is Initialization).