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.
Related
I have a project in which I have to allocate 1024 bytes when my program starts. In C++ program.
void* available = new char*[1024];
I write this and I think it is okay.
Now my problem starts, I should make a function that receives size_t size (number of bytes) which I should allocate. My allocate should return a void* pointer to the first bytes of this available memory. So my question is how to allocate void* pointer with size and to get memory from my available.
I'm a student and I'm not a professional in C++.
Also sorry for my bad explanation.
It looks like you're trying to make a memory pool. Even though that's a big topic let's check what's the minimal effort you can pour to create something like this.
There are some basic elements to a pool that one needs to grasp. Firstly the memory itself, i.e. where do you draw memory from. In your case you already decided that you're going to dynamically allocate a fixed amount of memory. To do it properly the the code should be:
char *poolMemory = new char[1024];
I didn't choose void* pool here because delete[] pool is undefined when pool is a void pointer. You could go with malloc/free but I'll keep it C++. Secondly I didn't allocate an array of pointers as your code shows because that allocates 1024 * sizeof(char*) bytes of memory.
A second consideration is how to give back the memory you acquired for your pool. In your case you want to remember to delete it so best you put it in a class to do the RAII for you:
class Pool
{
char *_memory;
void *_pool;
size_t _size;
public:
Pool(size_t poolSize = 1024)
: _memory(new char[poolSize])
, _pool(_memory)
, _size(poolSize)
{
}
~Pool() { delete[] _memory; } // Forgetting this will leak memory.
};
Now we come to the part you're asking about. You want to use memory inside that pool. Make a method in the Pool class called allocate that will give back n number of bytes. This method should know how many bytes are left in the pool (member _size) and essentially performs pointer arithmetic to let you know which location is free. There is catch unfortunately. You must provide the required alignment that the resulting memory should have. This is another big topic that judging from the question I don't think you intent to handle (so I'm defaulting alignment to 2^0=1 bytes).
#include <memory>
void* Pool::allocate(size_t nBytes, size_t alignment = 1)
{
if (std::align(alignment, nBytes, _pool, _size))
{
void *result = _pool;
// Bookkeeping
_pool = (char*)_pool + nBytes; // Advance the pointer to available memory.
_size -= nBytes; // Update the available space.
return result;
}
return nullptr;
}
I did this pointer arithmetic using std::align but I guess you could do it by hand. In a real world scenario you'd also want a deallocate function, that "opens up" spots inside the pool after they have been used. You'd also want some strategy for when the pool has run out of memory, a fallback allocation. Additionally the initially memory acquisition can be more efficient e.g. by using static memory where appropriate. There are many flavors and aspects to this, I hope the initial link I included gives you some motivation to research a bit on the topic.
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 would like to write me own class String which will have interface similar to std::string. String class shall not use dynamic memory allocation.
I need to have a c-tor:
String(char* ptrToFirstCharInTab, char* ptrToLastElementInTab);
And there should be tab which contains different (not know) number of element, so I do not know size while compiling.
In my opinion it's impossible, because if we do not know size of our array before compilation we can not create it without dynamic allocation - of course creating buffer for 500 char and then String class can be only 500 it' not my expections.
Do you have any idea? Maybe is any way to create buffor wchich I will shrink to fit? Thanks for help!
You asked:
Do you have any idea? Maybe is any way to create buffor wchich I will shrink to fit?
In theory, yes you can. You can use a pre-allocated buffer as your heap memory. However, you'll have to write your own code to manage that buffer. Doable but not something I would recommend.
You asked:
Is it possible to create class String without using heap in C++?
In fact, yes, it possible to dynamicly allocate memory on the stack by using _alloca or similiar platform dependent function. See this other answer for more details:
C++ How to allocate memory dynamically on stack?
I would recommend against it and be absolutely sure that was the best alternative before commencing.
Update:
I created an example with inlined constructer for demonstration purpose using gcc:
Compiler explorer Link:
https://godbolt.org/z/M1F5VD
Full code:
#include <alloca.h>
struct String {
__attribute__((always_inline)) inline String(size_t size) {
bytes= static_cast<char*>(alloca( size ));// alloca() memory gets allocated here
}
char* bytes;
};
int workWithString( )
{
//std::string teststr("test");
String mystrclass(1000);
mystrclass.bytes[0] = 'a';
mystrclass.bytes[1] = 0;
return 0;
} // alloca() memory only gets freed here
int main() {
return workWithString();
}
I'm a bit confused with your question. You want to have std:: string without a heap and without size restrictions. Sorry to bring this to you: you can't have infinite memory.
If you have an pool of memory you want to dedicate to strings without it being fixed size for each string, an allocator can do so.
The default allocator for the containers does new, however you can replace it without having to duplicate the internals of string.
Suppose I have the following snippet.
int main()
{
int num;
int* cost;
while(cin >> num)
{
int sum = 0;
if (num == 0)
break;
// Dynamically allocate the array and set to all zeros
cost = new int [num];
memset(cost, 0, num);
for (int i = 0; i < num; i++)
{
cin >> cost[i];
sum += cost[i];
}
cout << sum/num;
}
` `delete[] cost;
return 0;
}
Although I can move the delete statement inside the while loop
for my code, for understanding purposes, I want to know what happens with the code as it's written. Does C++ allocate different memory spaces each time I use operator new?
Does operator delete only delete the last allocated cost array?
Does C++ allocate different memory spaces each time I use operator new?
Yes.
Does operator delete only delete the last allocated cost array?
Yes.
You've lost the only pointers to the others, so they are irrevocably leaked. To avoid this problem, don't juggle pointers, but use RAII to manage dynamic resources automatically. std::vector would be perfect here (if you actually needed an array at all; your example could just keep reading and re-using a single int).
I strongly advise you not to use "C idioms" in a C++ program. Let the std library work for you: that's why it's there. If you want "an array (vector) of n integers," then that's what std::vector is all about, and it "comes with batteries included." You don't have to monkey-around with things such as "setting a maximum size" or "setting it to zero." You simply work with "this thing," whose inner workings you do not [have to ...] care about, knowing that it has already been thoroughly designed and tested.
Furthermore, when you do this, you're working within C++'s existing framework for memory-management. In particular, you're not doing anything "out-of-band" within your own application "that the standard library doesn't know about, and which might (!!) it up."
C++ gives you a very comprehensive library of fast, efficient, robust, well-tested functionality. Leverage it.
There is no cost array in your code. In your code cost is a pointer, not an array.
The actual arrays in your code are created by repetitive new int [num] calls. Each call to new creates a new, independent, nameless array object that lives somewhere in dynamic memory. The new array, once created by new[], is accessible through cost pointer. Since the array is nameless, that cost pointer is the only link you have that leads to that nameless array created by new[]. You have no other means to access that nameless array.
And every time you do that cost = new int [num] in your cycle, you are creating a completely new, different array, breaking the link from cost to the previous array and making cost to point to the new one.
Since cost was your only link to the old array, that old array becomes inaccessible. Access to that old array is lost forever. It is becomes a memory leak.
As you correctly stated it yourself, your delete[] expression only deallocates the last array - the one cost ends up pointing to in the end. Of course, this is only true if your code ever executes the cost = new int [num] line. Note that your cycle might terminate without doing a single allocation, in which case you will apply delete[] to an uninitialized (garbage) pointer.
Yes. So you get a memory leak for each iteration of the loop except the last one.
When you use new, you allocate a new chunk of memory. Assigning the result of the new to a pointer just changes what this pointer points at. It doesn't automatically release the memory this pointer was referencing before (if there was any).
First off this line is wrong:
memset(cost, 0, num);
It assumes an int is only one char long. More typically it's four. You should use something like this if you want to use memset to initialise the array:
memset(cost, 0, num*sizeof(*cost));
Or better yet dump the memset and use this when you allocate the memory:
cost = new int[num]();
As others have pointed out the delete is incorrectly placed and will leak all memory allocated by its corresponding new except for the last. Move it into the loop.
Every time you allocate new memory for the array, the memory that has been previously allocated is leaked. As a rule of thumb you need to free memory as many times as you have allocated.
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.