Can someone explain the point of dynamic memory allocation in C++?
What is the practical scenario/example/use of dynamic memory allocation and vector of pointers in C++? - Stack Overflow
When should I be using dynamic memory?
Variables have a life time that is bound to the function they are defined in (unless they are global or static). So if you want something that exists beyond the scope of a given function, you must either pass the object itself around (call/return by value) or allocate the object dynamically and pass around a pointer to it. For large objects, the latter is much faster, and for really large objects, the only option. Another use case is if you don't know the size of something at compile time. It could for example be that the amount of elements you need to store in some program depends on input from the user, something read from a file or perhaps some information acquired through the network. Then you typically also need to use dynamic memory allocation to get just the right amount of storage that you need.
Now, as people have pointed out, dynamic memory doesn't necessarily have to be, and shouldn't be, allocated and freed manually using new and delete. You typically use dynamic memory through container classes (vector, map, etc.) or through smart pointers (unique_ptr, shared_ptr, etc.). These all take care of the new-ing and delete-ing for you. It still happens under the hood, but you don't have to explicitly manage the life time of the dynamically allocated memory.
More on reddit.comWhat is the use of dynamic memory allocation?
this is a pretty good explanation https://stackoverflow.com/questions/18217525/why-or-when-do-you-need-to-dynamically-allocate-memory-in-c
NASA/JPL also mentions the following about malloc() when designing safety critical software
3: Do not use dynamic memory allocation after initialization.
source: http://pixelscommander.com/wp-content/uploads/2014/12/P10.pdf
More on reddit.comWhat is an example of memory allocation?
What are the 4 dynamic memory allocation functions?
Videos
I am learning C++ and I am at a point where I'm learning about memory. I read that normally declared data (like int x = 5) are automatically managed by the compiler, but dynamically allocated ones aren't. With that, I am kinda having a hard time seeing why dynamically allocated memory is useful.
- Static allocation: You know the requested memory size at compile time, so you can define an array like:
int buf[20]; // This is an array of 20 ints
- Dynamic allocation: You allocate the storage at runtime. For example the needed array size is an input to your progam:
int *buf = new int[n]; // where n is some runtime known number.
<some code...>
delete[] buf; // In this case you must release the memory when you don't need it anymore
For example an usecase of an array of pointers is polymorphism. You have a class Base, and you have Derived classes (ie Der1, Der2, Der3). You want to store many object from those derived classes in an array. But you can't since the array type tells you what can you store in them. So in this case you can store the pointers to the Der* objects in the array, as if it is a Base* object.
struct Base
{
virtual ~Base() {};
virtual void doSomething() = 0;
};
struct Der1 : Base
{
virtual void doSomething(); // define what Der1 does for this function
};
struct Der2 : Base
{
virtual void doSomething(); // define what Der2 does for this function
};
struct Der3 : Base
{
virtual void doSomething(); // define what Der3 does for this function
};
int main()
{
// You allocate memory for Base* types so this is an array of pointers
Base* some_array[3]; // It can be also dynamically allocated
// And now you can store Der* in this array as:
some_array[0] = new Der1();
some_array[1] = new Der2();
some_array[2] = new Der3();
// There we did dynamic allocation with new!!!
// Since our objects are not in the some_array array, but somewhere in the memory,
// and we store pointers to them in the array
// And you can do:
some_array[0]->doSomething();
some_array[1]->doSomething();
some_array[2]->doSomething();
// Release the DYNAMICALLY!! allocated things
delete some_array[0];
delete some_array[1];
delete some_array[2];
}
But there are many other usecases. This is just one of them...
Dynamic memory allocation: when you need to use arrays but don't know what size will be required and the compiler doesn't support run-time size on the array allocations. std::vector is useful.
Vector of pointers: when you need to sort an array of big objects, you shouldn't swap elements directly because some of them (like arrays) can not evade extra copies of POD elements. Swapping pointers is enough here and is faster to do against copying millions of elements.
std::vector<std::shared_ptr<float>> bigArrays;
... allocate ...
// sort elements(big objects/arrays) on their elements at index
std::sort(bigArrays.begin(),bigArrays.end(),
[]
(std::shared_ptr<float> e1, std::shared_ptr<float> e2)
{
return e1[index]<e2[index];
}
);
Sometimes you have an array of atomics:
// behold the false-sharing!
std::vector<std::atomic<int>> atomics;
atomics.push_back(std::atomic<int>());
not possible to dynamically build after the initialization. Their copy-constructors are deleted. Instead, use a vector of pointers:
std::vector<std::shared_ptr<std::atomic<int>>> atomicPtrs;
atomicPtrs.push_back(std::make_shared<std::atomic<int>>());
Sometimes the data pointed to belongs to another domain:
std::vector<float *> gpuMatrices(100);
for(int i=0;i<100;i++
cudaMalloc ( gpuMatrices.data()+i, 1024*1024*sizeof(float) );
so that you can't work with plain vectors anymore. Then storing those (e.g. cuda) buffer pointers in a vector lets you manage the resources.
Sometimes the vector has to support different derived classes of a base class:
std::vector<Dog,Cat,Horse,Elephant> animals;
it won't work. Need to have this:
std::vector<Iquackable*> animals(100);
animals[0]=(Iquackable*)getDuckPtr();
animals[0]->quack(); // "quack"
animals[1]=(Iquackable*)getCatPtr();
animals[1]->quack(); // "meow"
Sometimes your matrix is so huge that you need to have each row of it local to its own numa node in a computation:
my_1TB_matrix[0]=getDataPtr(x,0); // numa_alloc_local(..) from another thread
my_1TB_matrix[1]=getDataPtr(x,1); // numa_alloc_local(..) from another thread
...
so that a CPU (of a multi-CPU system) working on its own row will have better timings.
Sometimes all you have is a pointer because they include each other:
std::vector<Node *> sparseOctree(5);
octree[0]=getRootNodePtr();
octree[1]=octree[0]->createChildNode();
octree[2]=octree[0]->createChildNode();
octree[3]=octree[1]->createChildNode();
octree[4]=octree[1]->createChildNode();
..
Sometimes you need to roll your own memory pool to make things faster:
std::vector<Memory *> heap(500);
heap[0] = allocateMemory();
heap[1] = allocateMemory(); freeMemory(heap[1]);
heap[2] = allocateMemory();
heap[3] = allocateMemory();
defragmentation(heap);
without touching the data the memory holds.