I'm using some dynamically allocated arrays of multiprecision variables (from the mpc-library) and wonder if it is necessary both to clear the variables and to delete the arrays to avoid memory leaks etc? In other words, is all the housekeeping in the snippet below necessary?
using namespace std;
#include <gmp.h>
#include <mpfr.h>
#include <mpc.h>
int main() {
int i;
mpc_t *mpcarray;
mpcarray=new mpc_t[3];
for(i=0;i<3;i++) mpc_init2(mpcarray[i], 64);
// Manipulations
for(i=0;i<3;i++) mpc_clear(mpcarray[i]);
delete [] mpcarray;
return 0;
}
Yes, it is necessary.
The general rule of life applies here:
"You should dispose what you use!"
If you don't it results in a memory leak or much worse an Undefined Behavior if the destructor of mpc_t contains code which produces side effects .
Dynamic memory is an feature which provides you explicit memory management for your program and if you use it(calling new or new []) then it is your responsibility to ensure its proper usage (deallocate it by calling delete or delete [] respectively).
Note that you are much better of to use auto/local variables instead of dynamically pointers.
And if you must, you should use smart pointers instead of raw pointers. They provide you advantages of dynamic memory minus the explicit memory management overhead.
Related
I am trying to create wrapper macros for allocating and de-allocating dynamic memory for my c++ application. So sometime we need to allocate just an object, and sometime need to allocate an array of objects, so we need new and new[size] respectively, and then we need to remember which delete to call, normal delete for objects and delete[] for arrays.
So, if I make it generic and always use new[1] for single object allocation and new[size] for arrays, I won't need to call specific delete in this case, delete[] would work all the time.
So my question is that, is there any performance or other drawback of this technique i.e using new[1] for single object memory allocation.
First: Please don't. This will obfuscate your code. Consider using memory management support from the STL. For example std::vector everywhere you use new[] and std::unique_ptr everywhere you use new. Raw new and delete are often unnecessary and a frequent source for bugs.
Regarding your question: You will waste memory. Using new[1] will allocate a bit more than the size of your allocated object. In front of the returned pointer there will be a bit space that tracks the size of the allocation such that delete[] will work without supplying the size to delete since the system can just read this size from the block in front of the pointer. For the user this extra space is pretty much invisible but of course you can feel the wasted memory if you overdo it. Just try the following code and look what the difference in memory consumption is (can ne checked i.e. with valgrind)
#include <vector>
// Comment out the following line for the other version
#define ARRNEW
int main () {
std::vector<int*> ptrs(10000);
for(int i = 0; i <ptrs.size(); ++i) {
#ifdef ARRNEW
ptrs[i] = new int[1];
#else
ptrs[i] = new int;
#endif
}
for(auto ptr: ptrs) {
#ifdef ARRNEW
delete[] ptr;
#else
delete ptr;
#endif
}
}
I tried to allocate dynamic memory for an array of empty queues using the malloc function, as the code shows. However, the output of (*pq).size() is incorrect -128, and calling (*pq).push() will cause an error. Where did I go wrong? How to allocate the memory correctly?
#include <stdio.h>
#include <stdlib.h>
#include <queue>
typedef std::queue<int> iq;
iq *pq;
int main() {
pq = (iq *) malloc(16 * sizeof(iq));
printf("%d\n", (*pq).size());
printf("%d\n", (*pq).empty());
// (*pq).push(12);
(*pq).pop();
printf("%d\n", (*pq).size());
free(pq);
return 0;
}
How to allocate memory for an array of queues by malloc?
Just like you did in your example. Technically, it's not the allocation that's wrong. Although, see †.
Where did I go wrong?
You only allocated some amount of memory for the queues. You never constructed any queue object into that block of memory. Dynamic objects are constructed using a new-expression. To construct an object into a block of memory allocated by malloc, you could use the placement-new syntax.
How to allocate the memory correctly?
By not using malloc.
† There is no good reason to use malloc in C++.
Here is a correct way to allocate dynamic memory for an array of 16 queues, as well as construct those queues:
std::vector<std::queue<int> > pq(16);
The vector will take care of numerous problems that you would shoot yourself in the foot otherwise. It will take care of constructing the elements as well as destroying them, avoids memory leaks and double removes, as well as more subtle issues like exception safety.
It's not clear if malloc is a requirement of your solution. A native C++ solution avoids most of the issues with readable semantics. See below.
In the code below, I've switched to using iostream and vector, as it frees you to reason about everything at the same level of abstraction. Malloc is a low-level C routine for allocating dynamic memory. You're already using std::queue, so it doesn't really make sense to mix malloc when a vector will do just fine.
Solution
#include <queue>
#include <iostream>
#include <vector>
using iq = std::queue<int>;
using vec = std::vector<iq>;
int main()
{
using namespace std;
vec pq;
pq.resize(16);
pq[0].empty();
cout << pq[0].size() << endl;
pq[0].push(12);
pq[0].push(13);
pq[0].push(11);
pq[0].pop();
cout << pq[0].size() << endl;
return 0;
}
Example Output
$main
0
2
I am writing a big code and I prepared a memory class in order to create and grow different types of arrays safely. In this class I keep track of the size of memory that allocated using sizeof when allocating a new pointer. However, I do not know how to keep track of the memory allocating.
Let me put my question in another way. For example suppose we allocate a new array at some point in the code:
double* array=new double[size];
and some place else we want to deallocate the memory without knowing the size, normally we use
delete [] array;
delete operator automatically frees the memory of array, is there any way to determine how many bytes does it free (supposing that we don't keep track of size)?
In general, the answer is no, because memory managers hide that kind of implementation-dependent information from you. Also, C++ doesn't provide any standard way of tracking how much memory is actually used/freed. There might be functions specific to a certain platform/operating system, but nothing that is 100% portable.
use a std::vector instead and when you delete it you can call this beforehand to find out how much was cleared: vec.capacity() * sizeof(OBJECT) will give you the amount of bytes stored in the vector.
To keep track of allocated memory you need to implement manuelly some kind of counting mechanism, for example with a static (private) member which counts the allocated bytes.
If you want to have full control over memory allocation and deallocations you should use amemory pool.
Home grown memory pools are fast, safe and relatively easy to implement - unless you want fancy stuff. Implementing such a mechanism will provide you will all kinds of information such as memory leaks too. Calculating the memory freed is also a breeze because the linked list holds the total memory allocated.
Click the big friendly button to dive in.
I realize another answer was already accepted, but here is how you write your own allocators if you wanted to very simply track memory arrays:
#include <map>
#include <iostream>
using namespace std;
map<void*,size_t> memmap; //put this as a global variable in an implementation file, and extern it in the header file.
class MyManagedClass{
public:
MyManagedClass(){}
void* operator new[](size_t sz){
void* out = operator new(sz*sizeof(MyManagedClass));
for(size_t i=0; i<sz; ++i)
*((MyManagedClass*)out+sz)=MyManagedClass::MyManagedClass();
memmap[out] = sz;
return out;
}
void operator delete[](void* t){
cout << "Freed units: " << memmap[t] << endl;
memmap.erase(t);
delete[] t;
}
};
int main(){
MyManagedClass* ip = new MyManagedClass[10];
delete[] ip;
system("pause");
}
I should mention that this is a scrappy way to do it, and you could probably make it nicer/generic with templates and a more thought out memory design lol.
I have been doing some research and still can't find a solution to my problem.
As far as I know, when we declare variables outside of a function, they are allocated within the heap, and that memory is not freed until the end of execution; unless we specifically do so with the delete function. I've tried the following functions to free the variables declared at the beginning of the code and none of them worked (getting a debug error in dbgdel.cpp): delete, delete [], free().
What am I doing wrong?
I will paste underneath a summarized version of the code. Any help is appreciated. Thank you!
(I know global variables are not usually desirable in proper programming, but is not my piece of code, I am just trying to fix it as it is.)
#include <stdio.h>
#include <conio.h>
#include <cv.h>
#include <highgui.h>
#include <cxcore.h>
#include "Viewer.h"
....
// Arrays
float z_base [5201][5201];
....
uchar maskThreshold [5200][5200];
...
void main(){
.....
delete [] z_base;
//free (z_base);
//delete z_base;
//free (&z_base);
}
As far as I know, when I declare variables outside of every function they are allocated within the heap
This is not true. In general, you only have to call delete or delete[] if you have allocated memory with new or new [] respectively.
There is no heap (in C++).
All memory is released at the end of execution.
delete what you new, delete[] what you new[].
void main is wrong (main must return int).
That is all.
You don't. The run-time will do it for you. As a rule of thumb, you only need to delete/delete[] that which you allocated with new/new[].
Also, note that globals are not allocated on the heap, but in static memory.
why i'm getting the memory leak errors without allocating or adding any elements to list below. should i just ignore it?
#define CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <list>
using std::list;
int main()
{
list <char*> roots;
_CrtDumpMemoryLeaks();
}
You are not giving the roots variable a chance to be destroyed before checking for memory leaks. If roots is destroyed first, you should notice that everything is cleaned up. Try this instead.
#define CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#include <list>
using std::list;
int main()
{
{
list <char*> roots;
}
_CrtDumpMemoryLeaks();
}
The list hasn't been destructed yet when you call _CrtDumpMemoryLeaks, so any allocation it has performed is treated as a memory leak. This has nothing to do with the char*: the same thing would happen with list<int>.
_CrtDumpMemoryLeaks simply reports any allocations that haven't been freed yet. It has no way of knowing that the list destructor is yet to run and perform deallocations.
If you do C++, then using std::string instead of char* might be a better practice.
Anyway, you must understand that the container holds pointers to chars, not the chars themselves. So, on destruction, it will free the memory occupied by the pointers, but not the pointed memory.
In short terms, it is up to you to free every char* before destroying/clearing the list.
In general it's better to do
_CrtSetDbgFlag(_CRTDBG_LEAK_CHECK_DF); (You might need other flags too...)
which causes the runtime to dump memory leaks before it exits than to explicitly call _CrtDumpMemoryLeaks. If you do that you can be sure that any local variables still in scope as well as any global variables will have been freed so any reported memory leaks are "real".