I am dynamically allocating memory at the beginning of a for using:
Candset_t* emptycandset(void) {
Candset_t* cset;
cset = (Candset_t*)malloc(sizeof(Candset_t));
cset->size = 0;
cset->maxsize = MAXSIZE;
cset->dptr = (Point_t*)malloc(MAXSIZE * sizeof(Point_t));
return cset;
}
whereby Candset and Point_t are both typedef.
later I free the memory at the end of the loop with:
void destroycandset(Candset_t* cset) {
free(cset->dptr);
free(cset);
}
The reason why I am doing this is because I want to reuse the same variable(memory space) in all the iterations of the loop.
This actually cause fragmentation of the heap. Hence, decreased performance. How can I solve this? is it possible to reinitiate a dynamically allocated space? How does this affect the dynamic memory?
Cheers
I am trying to reuse a dynamically allocated memory. However, using malloc and free cause fragmentation of the heap.
Do you know any way to avoid memory fragmentation?
typedef struct point {
double x, y;
unsigned int dst;
} Point_t;
typedef struct candset {
unsigned int size;
unsigned int maxsize;
Point_t* dptr;
} Candset_t;
This is what the struct data look like.
I can't tell what the size of the dptr and Candset_t will be; Hence, I have to allocate them dynamically. It make no difference when using new and delete for c++ only.
For structures smaller than 1 MB whose lifetime is simple, don't use dynamic allocation at all.
Just create a Candset_t in automatic storage (on the stack).
Automatic storage provides memory extremely efficiently.
If your object is "simple" enough to malloc-and-modify, it is also free to create in automatic storage.
There are people who are used to languages like Java or C#, where creating an object is inherently expensive.
In C++, creating an object can be literally free. It can also be expensive. How expensive it is depends on the properties of the object.
Because objects in C++ carry less baggage than in garbage collected languages, the "free" case is really, really free.
To make an object effectively free to use, ensure that it doesn't use dynamically allocated memory at construction time, and to be extra sure avoid virtual functions (sometimes these can also be free). Next, don't use new or malloc to create it.
Here is a simple "free" class:
struct Candset_t {
std::size_t size;
Point_t data[MAXSIZE];
};
so long as MAXSIZE isn't really big, like in the many 1000s, this is going to be a better plan than the original.
If this doesn't work, then you can just move the declaration of Candset_t up a scope, and reuse it. You do not want to reallocate dptr, but instead write code to clear the memory in it.
Generally, calls to malloc or new take 100x or more the time of a typical line of C++ code. So avoid them in tight loops.
Related
I am aware of the differences between free and delete in C++. But one thing I never understood is why in C malloc/free can allocate de-allocate both single 'objects' and arrays but in C++ we need to use the correct new/delete vs new[]/delete[] pair.
Searching on Stackoverflow, it seems that in C++, new[] allocates extra memory to hold the size of the allocated array and new only allocates the memory to the object itself. And because of that, you should be aware of this extra overhead.
If the previous paragraph is indeed the case, then how malloc/free handles this overhead? Or they just accept this overhead? And if it is tolerable in C, why not in C++?
On the other hand, in case it's not because of memory overhead, but because of calling constructors and destructors, couldn't the compiler be smart enough to generate the appropriate code under the hood and let the programmer just write new/delete for both single objects and arrays of objects?
I am writing a compiler for a toy language whose semantics is similar to C++ and it seems that it is possible to let the compiler decides how to allocate and de-allocate only using new/delete, but as C++ uses new/delete and new[]/delete[], maybe there's a catch that I am not seeing right now. Maybe something related to polymorphism and virtual tables?
If you're curious, my naive idea is to simple allocate an integer together with the object/array where this integer is the size of the array or simple 1 in case of being an object. Then, when calling delete, it checks the value of the integer, if it is 1, it calls the destructor. If it greater than 1, then it iterates the array calling the destructor to each object in the array. As I said, it seems to work and would let the programmer just write new/delete instead of new/delete vs new[]/delete. But then again, maybe there's a catch that I am not seeing.
Edited part:
After some answers, I decided to try to provide some pseudo-code and a better background.
In C language, memory allocations are usually made with malloc() and de-allocations with free(). Either if you are allocating a single POD, a single struct or an array, malloc() fits all these cases. There is no need for different versions of malloc() if you are allocating a single struct vs a malloc_array() version if you are allocating an array. At least at the public API level. In other words, it seems it doesn't matter if you are allocating a few bytes or many bytes, there will be no overhead for bookkeeping the allocation size information.
As many of you are aware, including myself, new and delete do more than just allocate and de-allocate memory. New allocate memory and call the constructor and delete calls the destructor and then de-allocate memory. But in C++, you need to be aware if you are allocating just a single object or an array of objects. In case you are allocating an array, you need to use the new[]/delete[] pair.
In C, if you implement a binary tree, nodes will be allocated with malloc and de-allocated with free and in C++ with new and delete. But if you are implementing something like the vector class in C++, in C you still would use malloc/free, but now in C++ you would need to use new[]/delete[] (considering a sane implementation without too much black magic).
Consider the following pseudo-code that is executed by the compiler. In this pseudo-code, the delete function somehow gets access to the malloc internals and knows how many bytes there are, which in turn can be easily used to calculate how many objects there are. As this delete implementation is using malloc internals to know how much memory is allocated, in theory there should be no overhead of bookkeeping.
// ClassType is a meta type only know by the compiler
// it stores a class info such as name, size, constructors and so on
void *new(ClassType c) {
// allocates memory with malloc. Malloc() do the storage bookkeeping
// note that somehow malloc is allocating just a single object
c *ptr = malloc(sizeof(c));
// now, call the constructor of the requested class
c.constructor(ptr);
// return the new object
return ptr;
}
void *new(ClassType c, size_t n) {
c *ptr = malloc(sizeof(c) * n);
// iterate over the array and construct each object
for (i = 0; i < n; ++i) {
c.constructor(ptr[i]);
}
return ptr;
}
// this delete version seems to be able to de-allocate both single
// objects and arrays of objects with no overhead of bookkeeping because
// the bookkeeping is made by malloc/free. So I would need
// just a new/delete pair instead of new/delete vs new[]/delete[]
// Why C++ doesn't use something like my proposed implementation?
// What low-level details prohibits this implementation from working?
void delete(ClassType c, void *ptr) {
// get raw information of how many bytes are used by ptr;
size_t n = malloc_internals_get_size(ptr);
// convert the number of bytes to number of objects in the array
n = c.bytesToClassSize(n);
c* castedPointer = (c*) ptr;
// calls the destructor
for (i = 0; i < n; ++i) {
c.destructor(castedPointer[i]);
}
// free memory chunk
free(ptr);
}
why in C malloc/free can allocate de-allocate both single 'objects'
Malloc doesn't create any objects. It allocates "raw memory" which doesn't contain any objects. Correspondingly, free doesn't destroy any objects. new expressions do create objects, and delete destroys an object, while delete[] destroys an array of objects.
In order for the language implementation to know how many objects need to be destroyed by delete[], that number has to be stored somewhere. In order for the language implementation to know how many objects need to be destroyed by delete, that number does not need to be stored anywhere because it is always one.
Storing a number is not free, and storing an unused number is an unnecessary overhead. The different forms of deletion exist so that the language implementation can destroy the correct number of objects without having to store the number of objects created by a non-array new.
then how malloc/free handles this overhead?
malloc/free doesn't have this overhead since it doesn't create or destroy objects. As such, there is nothing that needs to be handled.
There is an analogous issue of storing the number of allocated bytes that malloc does need to deal with. There is no analogous separate function for allocation or freeing of a single byte. This may be because such use case is probably rare. Malloc has more clever ways of dealing with storing this because allocating more memory than is needed is not observable, while such trick is not possible with number of objects because creation and destruction of objects is observable (at least in case of non-trivial types).
new typically deals with the issue of storing the number of allocated bytes through using malloc internally.
couldn't the compiler be smart enough to generate the appropriate code under the hood
Not without some kind of overhead, no. With overhead yes, it could.
But then again, maybe there's a catch that I am not seeing.
I'm not sure if it is a catch that you haven't seen, but the catch with your idea is the overhead of the integer that is to be allocated even when a single object is allocated.
Some clever implementations of malloc don't actually keep track of the size per allocation (by clever use of rounding up), thus it have extremely low space overhead. They'll allocate a large block of memory, and anytime a dev allocates <64 bytes, it'll just use the next 64 bytes of this block, and mark a single bit elsewhere that tracks that this block of 64 bytes is now in use. Even if the user only wants to allocate 1 byte, it hands out a whole block. This means each allocation has only a single bit overhead, so every 8 allocations has a shared byte of overhead. Practically nothing. (There are far smarter strategies than this, this is just a simplified example)
new and delete can share this super-low-overhead implementation, because delete knows to always destroy one object, regardless of the amount of space it actually has. This is again, super fast, and has low space overhead.
delete[] can't do that because it has to know exactly how many destructors to call. So it has to keep track of how many items are in the array, up to std::size_t, which means ~4 bytes have to be added to every new[]. If the data requires an alignment >4, then each allocation also has to have wasted padding bytes between the count and the first item in the array. And delete[] therefore has to know how to look past the padding, find the count, so it knows exactly how many objects to destroy. This takes both time and more space, for every allocation.
C++ gives you the choice between "always works, but slower and bigger", and "only works for one item, but faster and smaller", so the program can run as fast as possible.
Not all implementations have a difference between new/delete vs new[]/delete[] but they exist because new expression act differently in case of array. thing is that the new expression is not just call to the new operator, underlying operators might be identical:
#include <iostream>
// class-specific allocation functions
struct X {
static void* operator new(std::size_t sz)
{
std::cout << "custom new for size " << sz << '\n';
return ::operator new(sz);
}
static void* operator new[](std::size_t sz)
{
std::cout << "custom new[] for size " << sz << '\n';
return ::operator new(sz);
}
};
int main() {
X* p1 = new X;
delete p1;
X* p2 = new X[10];
delete[] p2;
}
But they maybe overloaded to different ones as well. It might be important difference for native compiler, if you're writing an interpreter or if you don't expect users to modify new\delete, you can do this differently. In C++ new expression call one constructor after allocating memory with provided function, new[] expression would call several and store the count. Of course if compiler got object-oriented memory model, like Java does, then array would be an object with property of size. Single object is just an array of one instance. And as you said, we won't need a separate delete expression.
I've always declared my arrays using this method:
bool array[256];
However, I've recently been told to declare my arrays using:
bool* array = new bool[256];
What is the difference and which is better? Honestly, I don't fully understand the second way, so an explanation on that would be helpful too.
bool array[256];
This allocates a bool array with automatic storage duration.
It will be automatically cleaned up when it goes out of scope.
In most implementations this would be allocated on the stack if it's not declared static or global.
Allocations/deallocations on the stack are computationally really cheap compared to the alternative. It also might have some advantages for data-locality but that's not something you usually have to worry about. But you might need to be careful of allocating many large arrays to avoid a stack overflow.
bool* array = new bool[256];
This allocates an array with dynamic storage duration.
You need to clean it up yourself with a call to delete[] later on. If you do not then you will leak memory.
Alternatively (as mentioned by #Fibbles) you can use smart-pointers to express the desired ownership/lifetime requirements. This will leave the responsibility of cleaning up to the smart-pointer class. Which helps a lot with guaranteeing deletion, even in cases of exceptions.
It has the advantage of being able to pass it to outer scopes and other objects without copying (RVO will avoid copying for the first case too in certain cases, but storing it as a data-member and other uses can't be optimized in the first case).
The first is allocation of memory on stack:
// inside main (or function, or non-static member of class) -> stack
int main() {
bool array[256];
}
or maybe as a static memory:
// outside main (and any function, or static member of class) -> static
bool array[256];
int main() {
}
The last is allocation of dynamic memory (in heap):
int main() {
bool* array = new bool[256];
delete[] array; // you should not forget to release memory allocated in heap
}
The advantage of dynamic memory is that it can be created with variable number of elements (not 256, but from some user input for example). But you should release it each time by yourself.
More about stack, static and heap memory and when you should use each is here: Stack, Static, and Heap in C++
The difference is static vs dynamic allocation, as previous answers have indicated. There are reasons for using one over the other. This video by Herb Sutter explains when you should use what. https://www.youtube.com/watch?v=JfmTagWcqoE It is just over 1 1/2 hours.
My preference is to use
bool array[256];
unless there's a reason to do otherwise.
Mike
I've thought about how I can improve the performance of reading of a list sort by an (unsigned) integer that is read in at the program start and won't change until the program exits. I thought about different possibilities but then I got an idea and I'd like to know if that's possible and if not, why not - because in my theory it should be possible for the computer.
I have a list with something like 10.000 entries, every entry has an unique ID (an the unique ID is not 0). Now what about allocating memory with the size object* pList = new(sizeof(object) * max_unique_id) and then deleting all the unused memory (check what unique id is not existing and free the memory at the position with the size sizeof(object))... you would be using only the needed memory and you could just access to a list entry with pList[unique_id] -> would be really, really fast... but you cannot delete a single element in a dynamic allocated array :/ At the program termination you can of course free all the elements, it's no problem to safe the pointer + sizes in a std::vector or sth like that.
That's why I'm asking if my theory is incorrect or if the system just does not allow it or where the problem is.
No, you can't control memory like that. However, it IS possible to cheat a little bit. If you are allocating big chunks of memory, you can make your own memory pool. That way, you can create the holes yourself and use that memory for other parts of your program.
I wouldn't recommend it though, as you may have issues with strict aliasing, as well as having to deal with more complexity in your code.
Rewinding just a little, you are forgetting about caching effects, which are significant. Keeping your objects packed closely together will likely have more effect on speed than making the lookup faster.
To achieve this you could use a simple hash to look up your objects, or you could just make a sparse index array of 16-bit indices.
You can, (though I have no idea why you want to), but you will have to write it as your own custom memory allocation and deallocation routine or class. Using the standard C++ library out of the box, you can't.
See some of the interfaces for allocating memory in C++
void* operator new ( std::size_t );
void* operator new[]( std::size_t );
void* operator new ( std::size_t, const std::nothrow_t&);
void* operator new[]( std::size_t, const std::nothrow_t&);
Taking void* operator new[]( std::size_t ); for example. There is absolutely no way the this routine knows how many objects are stored in the memory region that will be returned.
Same with it's matching function
void operator delete[]( void* ptr );
it only takes a void pointer, there is absolutely no way it knows how many you want to delete. The memory allocator that provided memory starting with that block pointed by ptr magically knows the size it allocated, and hence deletes it appropriately
Use placement new.
object* pList = new(sizeof(object) * max_unique_id)
Do not do this. new is NOT malloc. But you also cannot do this instead:
object* pList = new object[max_unique_id];
delete object[1];
C++ does not allow to delete individually allocated elements of a dyanmically allocated array with a simple delete.
C++ allows you to create an object in a pre-allocated memory space by using placement new. In this case, you must manually call the constructor with a call to placement new and the destructor.
Reference: Malloc and constructors
A* a = (A*)malloc(sizeof(A));
new (a) A();
a->~A();
free(a);
In other words, supply the exact place where you want a specific object to be created. I would suggest that you use a loop:
// Allocate the space using malloc()
object* pList = std::malloc(sizeof(object) * max_unique_id);
// Allocate using a loop. I would not trust a parallelization of this code.
// Doing memory allocation in parallel without the proper locks and stuff
// is probably wrong.
for (auto i = 0; i < max_unique_id; ++i) {
// Supply the point as the argument to placement new.
new (&pList[i]) object(/* arguments go here */);
}
Then, when you're done using a certain object, say i = 20...
// Select the object
object* todelete_object = pList[i];
// Manually call the destructor.
todelete_object->~object()
// Now, free the memory.
std::free(todelete_object);
I use std::malloc() and std::free() as defined in the C++-style C standard library includes.
Couldn't find exact answer to the question:
Is freeing memory and allocating again the only way to reallocate memory without using cstdlib? If not so, then what are the possible solutions?
Thanks in advance.
If you are implementing your own vector class, then you do need to properly copy the contents of the vector, not use realloc, since you don't know what the object itself is doing when it is being copied (or in C++11 for relevant cases, moved). Imagine for example that you have an object that does something like this:
class B;
class A
{
private:
B* bp;
public:
A(B *p) : bp(p)
{
}
};
class B
{
public:
A a;
B() : A(this)
{
...
}
};
MyVector<B> v;
If you copy the object to a different address, without calling the constructor, the bp pointer in A will point to some "random" place. That would be a pretty nasty bug to try to find.
[And yes, there is a bunch of stuff missing in the above classes - it is not meant as a complete class declaration, etc, etc]
Perhaps you mean like what is done with a std::vector (or other container) when you load it with memory, remove all the elements, then call clear to free the memory, then allocating new items within it, thus allocating more memory? In this case, as the memory in the container grows, the container may realloc its memory as needed.
Since you mention you are creating a Vector:
In projects where we needed to do this because we did not have a vector implementation (embedded), it is common to allocate a set chunk of memory larger than what is intiially required to prevent constant memory reallocations, which incur large copy costs and cause memory fragmentation. A common scheme was to allocate a "reasonable" size for the app, then double that size if the limit is reached. If the user ever requested the buffer be reduced in size, or set to a size at initialization, then we ignore this heuristic and use the requested size.
int* Array;
Array = new int[10];
delete[] Array;
The delete knows the count of allocated memory. I Googled that it stores it in memory, but it's compiler dependent. Is there anyway to use get this count?
Actually, the heap knows how large each allocation is. However, that's not something that you can access easily, and it is only guaranteed to be greater than or equal to the amount requested. Sometimes more is allocated for the benefit of byte alignment.
As Ben said though, the implementation does know in certain circumstances how many objects are in the array so that their destructors can be called.
There is no standard way to retrieve the number of elements after construction. In fact, for an int array, it is probably NOT stored anywhere. The count is only necessary for arrays of elements with non-trivial destructors, so that delete[] can call the right number of destructors. In your example, there aren't any destructor calls, since int doesn't have a destructor.
There's no way to get the number of elements of a dynamically allocated array after you allocate it.
The one way to rule them all
However, you can store it beforehand:
int* Array;
size_t len = 10;
Array = new int[len];
delete[] Array;
Custom class
If you don't like that, you could create your own class:
class IntArray
{
public:
int* data;
size_t length;
IntArray(size_t);
~IntArray();
};
IntArray::IntArray(size_t len)
{
length = len;
data = new int[len];
}
IntArray::~IntArray()
{
length = 0;
delete data;
data = NULL;
}
std::vector
The method I recommend is to use std::vector:
std::vector<int> Array (10, 0);
You can use it just like a regular array... with extra features:
for(size_t i = 0; i < Array.size(); ++i)
Array[i] = i;
There are likely one or two counts of the number of elements in such an allocation depending upon the type and the implementation that you are using though you can't really access them in the way you probably want.
The first is the accounting information stored by the actual memory manager that you are using (the library that provides malloc). It will store that a record of some size has been allocated in the free store of the system (heap or anonymous memory allocation are both possible with the glibc malloc for example). This space will be at least as large as the data you are trying to store (sizeof(int)*count+delta where delta is the C++ compiler's tracking information I talk about below), but it could also be larger, even significantly so.
The second count is a value kept by the compiler that tells it how to call destructors on all the elements in the array (the whole magic of RAII), but that value is not accessible and could probably even be done without directly storing the information, though that would be unlikely.
As others have said, if you need to track the information on allocation size you probably want to use a vector, you can even use it as an actual array for the purpose of pointer math if need be (see http://www.cplusplus.com/reference/stl/vector/ for more on this).
Who says that there actually is one?
This stuff depends on the implementation and as such is uninteresting for you, me or whoever wants to know it.
C++ generally intentionally doesn't allow you access to that information, because arrays are simple types that do not keep that information associated with them. Ultimately that information must be stored, but the compiler is free to figure out how, where, and when by the C++ standards to allow for optimization in the assembly.
Basically, either store it yourself somewhere, or (better, most of the time), use std::vector.
No, you need to keep track of it yourself if you need to know.
Many people like using a std::vector if it's not a fixed size. std::vector keeps track of the size allocated for you.