C++: Reallocating memory without cstdlib - c++

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.

Related

Reinitialize dynamically allocated memory

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.

Does an empty vector occupy as much space as a pointer to a type that is currently set to nullptr?

I have a class:
class Foo{
std::vector<Sprite*> vec;
Sprite* bar = nullptr;
}
I then do:
Foo zoom;
At this point in program execution, which occupies more space ? vec or bar ?
EDIT:
In the following situation, if I do: Foo zoom; Which would occupy less space:
class Foo{
Sprite* bar1 = nullptr;
Sprite* bar2 = nullptr;
Sprite* bar3 = nullptr;
}
or
class Foo{
std::vector<Sprite*> vec;
}
In this code:
class Foo{
std::vector<Sprite*> vec;
Sprite* bar = nullptr;
};
bar will be the size of a pointer, which is platform-dependent. Often, it will be either 32 bits (4 bytes) or 64 bits (8 bytes).
vec will be the size of a std::vector object, which is dependent on how your standard library has been implemented.
So we can't really say with absolute certainty, but we can make a pretty good guess based on what std::vector is required to do by the standard that an object of that type will be larger than a single pointer.
How much larger? Hard to say. Will it matter? No.
Resist the urge to try and build your own std::vector by declaring an array of pointers*. You will not outsmart the compiler. You'll end up with code that is both larger and slower than if you'd used the standard library's classes. That's what they are there for.
__
* Unless your memory profiler is actually telling you that there is a problem here.
The standard makes no guarantees. In practise, the vector object must contain a pointer to the dynamically allocated memory and then something to say how much of that dynamic memory is in use, and how much is allocated.
Those somethings could either be pointers or counts. In practise the memory consumption of either will be the same.
Thus typically, sizeof(vec) == 3*sizeof(bar).
A vector with a small buffer optimization (where "small" vectors are allocated directly in the object), might be bigger.
Both size of a pointer and size of a std::vector are not defined by the standard, so you need to figure out these numbers yourself on your target platform.
To get the size of a pointer to class, you need to write
sizeof(Spirit*)
Or create a new pointer and get its sizeof.
With std::vector the situation is a bit more complicated as some of the memory in it is allocated on stack (to store the information about the std::vector itself, like pointer to the data, or maybe its size), and some is allocated on heap (the data itself). To get the total amount of memory std::vector uses, you need to sum both of these values:
std::vector<Spirit*> vs;
sizeof(vs) + vs.capacity() * sizeof(Spirit*)
On my particular computer and compiler (x64, MSVC++ 2015) total amount of memory an empty std::vector uses is 24 bytes. Please note that on your target platform the value may or may not be different.

C++ create array of objects (from different classes)

I need to create a array that holds objects from multiple classes.
Example
class baseClass
{
//
};
class first : baseClass
{
//
};
class second : baseClass
{
//
};
How do I create array that can hold first and/or second object inside it?
It is somewhat of a home-task for me so I am forced to use arrays, I already searched and know that it is done with boost libraries ans such but I have no option here guys...
The best practice for that would be to create an array of smart pointers - preferably either one of the Boost or C++11 versions - to the base class. Making it a pointer array eliminates the risk of "slicing" your objects when you access them. Using smart pointers reduces the risk of memory leaks. Making it a base class pointer means that either derived class can be stored there safely.
baseClass *array[10];
baseClass **array2 = new baseClass *[size];
This is the simplest and most dangerous way. You have to be careful about the lifetime of the objects in order to avoid leaking or double freeing. You also have to be careful with the array's allocation and deallocation, especially if you have to change the size at runtime.
std::vector<baseClass*> vec;
This improves the previous example because the vector handles the memory of the array for you, but you still have to be careful with the baseClass pointers.
std::vector<boost::variant<first,second> > vec2;
This is another improvement that eliminates the need to manually allocate or deallocate memory for the objects, and it's type safe in terms of accessing the objects as firsts or seconds. You can't mistake one kind of object for another.
std::vector<std::unique_ptr<baseClass>> vec3;
With this option you can still confuse objects of different types for each other, but it uses only the standard library and you still don't have to manage the lifetime of the objects you allocate. It does use C++11 though.
Also, if you don't need a dynamic array you can use std::array<...,size>
std::array<std::unique_ptr<baseClass>,10> array3; has absolutely zero space or time overhead at runtime over baseClass *array[10];, and is much safer. (zero overhead, assuming a decent implementation)
If you can't use libraries you need an array of pointers like:
baseClass *array[123];
array[0] = new first();
array[1] = new second();
and no slicing will occur. (don't forget to delete everything)

Does a vector have to store the size twice?

This is a rather academic question, I realise it matters little regarding optimization, but it is just out of interest.
From what I understand, when you call new[size], additional space is allocated to store the size of the allocated array. This is so when delete [] is called, it is known how much space can be freed.
What I've done is written how I think a vector would roughly be implemented:
#include <cstddef>
template <class T>
class Vector
{
public:
struct VectorStorage
{
std::size_t size;
T data[];
};
Vector(std::size_t size) : storage(new VectorStorage[size])
{
storage->size = size;
}
std::size_t size()
{
return storage->size;
}
~Vector()
{
delete[] storage;
}
private:
VectorStorage* storage;
};
As far as I can tell, size is stored twice. Once in the VectorStorage object directly (as it needs to be so the size() function can work) but again in a hidden way by the compiler, so delete[] can work.
It seems like size is stored twice. Is this the case and unavoidable, or is there a way to ensure that the size is only stored once?
std::vector does not allocate memory; std::allocator, or whatever allocator you give the vector, is what allocates the memory. The allocator interface is given the number of items to allocate/deallocate, so it is not required to actually store that.
Vectors don't usually store the size. The usual implementation keeps a pointer past the end of the last element and one past the end of the allocated memory, since one can reserve space without actually storing elements in it. However, there is no standard way to access the size stored by new (which may not be stored to begin with), so some duplication is usually needed.
Yes. But that's an implementation detail of the heap allocator that the compiler knows nothing about. It is almost certainly not the same as the capacity of the vector since the vector is only interested in the number of elements, not the number of bytes. And a heap block tends to have extra overhead for its own purposes.
You have size in the wrong place -- you're storing it with every element (by virtue of an array of VectorStorage), which also contains an array (per instance of VectorStorage) of T. Do you really mean to have an array inside an array like that? You're never cleaning up your array of T in your destructor either.

What's the difference between these two classes?

Below, I'm not declaring my_ints as a pointer. I don't know where the memory will be allocated. Please educate me here!
#include <iostream>
#include <vector>
class FieldStorage
{
private:
std::vector<int> my_ints;
public:
FieldStorage()
{
my_ints.push_back(1);
my_ints.push_back(2);
}
void displayAll()
{
for (int i = 0; i < my_ints.size(); i++)
{
std::cout << my_ints[i] << std::endl;
}
}
};
And in here, I'm declaring the field my_ints as a pointer:
#include <iostream>
#include <vector>
class FieldStorage
{
private:
std::vector<int> *my_ints;
public:
FieldStorage()
{
my_ints = new std::vector<int>();
my_ints->push_back(1);
my_ints->push_back(2);
}
void displayAll()
{
for (int i = 0; i < my_ints->size(); i++)
{
std::cout << (*my_ints)[i] << std::endl;
}
}
~FieldStorage()
{
delete my_ints;
}
};
main() function to test:
int main()
{
FieldStorage obj;
obj.displayAll();
return 0;
}
Both of them produces the same result. What's the difference?
In terms of memory management, these two classes are virtually identical. Several other responders have suggested that there is a difference between the two in that one is allocating storage on the stack and other on the heap, but that's not necessarily true, and even in the cases where it is true, it's terribly misleading. In reality, all that's different is where the metadata for the vector is allocated; the actual underlying storage in the vector is allocated from the heap regardless.
It's a little bit tricky to see this because you're using std::vector, so the specific implementation details are hidden. But basically, std::vector is implemented like this:
template <class T>
class vector {
public:
vector() : mCapacity(0), mSize(0), mData(0) { }
~vector() { if (mData) delete[] mData; }
...
protected:
int mCapacity;
int mSize;
T *mData;
};
As you can see, the vector class itself only has a few members -- capacity, size and a pointer to a dynamically allocated block of memory that will store the actual contents of the vector.
In your example, the only difference is where the storage for those few fields comes from. In the first example, the storage is allocated from whatever storage you use for your containing class -- if it is heap allocated, so too will be those few bits of the vector. If your container is stack allocated, so too will be those few bits of the vector.
In the second example, those bits of the vector are always heap allocated.
In both examples, the actual meat of the vector -- the contents of it -- are allocated from the heap, and you cannot change that.
Everybody else has pointed out already that you have a memory leak in your second example, and that is also true. Make sure to delete the vector in the destructor of your container class.
You have to release ( to prevent memory leak ) memory allocated for vector in the second case in the FieldStorage destructor.
FieldStorage::~FieldStorage()
{
delete my_ints;
}
As Mykola Golubyev pointed out, you need to delete the vector in the second case.
The first will possibly build faster code, as the optimiser knows the full size of FieldStorage including the vector, and could allocate enough memory in one allocation for both.
Your second implementation requires two separate allocations to construct the object.
I think you are really looking for the difference between the Stack and the Heap.
The first one is allocated on the stack while the second one is allocated on the heap.
In the first example, the object is allocated on the stack.
The the second example, the object is allocated in the heap, and a pointer to that memory is stored on the stack.
the difference is that the second allocates the vector dynamically. there are few differences:
you have to release memory occupied by the vector object (the vector object itself, not the object kept in the vector because it is handled correctly by the vector). you should use some smart pointer to keep the vector or make (for example in the destructor):
delete my_ints;
the first one is probably more efficient because the object is allocated on the stack.
access to the vector's method have different syntax :)
The first version of FieldStorage contains a vector. The size of the FieldStorage class includes enough bytes to hold a vector. When you construct a FieldStorage, the vector is constructed right before the body of FieldStorage's constructor is executed. When a FieldStorage is destructed, so is the vector.
This does not necessarily allocate the vector on the stack; if you heap-allocate a FieldStorage object, then the space for the vector comes from that heap allocation, not the stack. If you define a global FieldStorage object, then the space for the vector comes from neither the stack nor the heap, but rather from space designated for global objects (e.g. the .data or .bss section on some platforms).
Note that the vector performs heap allocations to hold the actual data, so it is likely to only contain a few pointers, or a pointer and couple of lengths, but it may contain whatever your compiler's STL implementation needs it to.
The second version of FieldStorage contains a pointer to a vector. The size of the FieldStorage class includes room for a pointer to a vector, not an actual vector. You are allocating storage for the vector using new in the body of FieldStorage's constructor, and you leaking that storage when FieldStorage is destructed, because you didn't define a destructor that deletes the vector.
First way is the prefereable one to use, you don't need pointer on vector and have forgot to delete it.
In the first case, the std::vector is being put directly into your class (and it is handling any memory allocation and deallocation it needs to grow and shrink the vector and free the memory when your object is destroyed; it is abstracting the memory management from you so that you don't have to deal with it). In the second case, you are explicitly allocating the storage for the std::vector in the heap somewhere, and forgetting to ever delete it, so your program will leak memory.
The size of the object is going to be different. In the second case the Vector<>* only takes up the size of a pointer (4bytes on 32bit machines). In the first case, your object will be larger.
One practical difference is that in your second example, you never release either the memory for the vector, or its contents (because you don't delete it, and therefore call its destructor).
But the first example will automatically destroy the vector (and free its contents) upon destruction of your FieldStorage object.