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.
Related
In the VST spec, a buffer of multichannel audio data is passed around.....
MyClass::ProcessDoubleReplacing(double **inputs, double **outputs, int frames)
{
//and accessed like this...
outputs[channel][sample] = inputs[channel][sample]
}
I want to create a similar "2d pointer array", but am not having much success. I can create a simple pointer and iterate through it reading/writing values....
double* samples;
samples[0] = aValue;
.... but am having a crash festival trying to implement something that will allow me to...
samples[0][0] = aValue;
What would be the correct way to implement this?
double* samples;
samples[0] = aValue;
That's really bad. :( Please don't do this! "sample" is just a pointer to somewhere in your memory.
The memory it points to is not allocated at all, but you're writing to this memory...
You can allocate a block of memory either from the heap or from the stack. However, the stack has a size limit (configured in your compiler settings) - so for larger blocks (like audio data) you would typically allocate it from the heap. But you have to take care, that you won't leak memory from the heap - the stack memory is automatic managed by the scope of your variable, so that's easier to start with.
In C/C++ you can allocate memory from the stack like this:
double samples[512];
then you can do stuff like:
samples[0] = aValue; // change value of 1st sample in sample buffer with 512 elements
or
double* pointerToSample = samples[255]; // point to 256ths sample in the sample buffer
pointerToSample[127] = aValue; // change value of 384ths sample (256+128) in our sample buffer with 512 elements
and so on...
BUT if you just do,
double* pointerToSample;
pointerToSample[127] = aValue;
You're actualing writing to unallocated memory! Your pointer points somewhere, but there is no allocated memory behind it.
Be carefull with this! Also never access pointerToSample if the samples variable is already out-of-scope: the memory pointerToSample points to is no longer allocated otherwise.
To allocate memory from the heap in C++ there is the keyword new (to allocate memory) and delete (to free memory afterwards) dynamically.
i.e.
double *samples = new double[512];
will allocate a block of memory for your sample data. But after using it, you have to manually delete it - otherwise you're leaking memory. So just do:
delete[] samples;
after you're finished with it.
Last but not least to answer your question how to create a two dimensional array to call the method ProcessDoubleReplacing()
int main(int argc, char ** argv){
/* create 2 dimensional array */
int** samplesIn = new int*[44100];
int** samplesOut = new int*[44100];
for(int i = 0; i < 44100; ++i){ // 1s # 44.1Khz
samplesIn[i] = new int[2]; // stereo
samplesOut[i] = new int[2]; // stereo
}
/* TODO: fill your input buffer with audio samples from somewhere i.e. file */
ProcessDoubleReplacing(samplesIn, samplesOut, 44100);
/* cleanup */
for(int i = 0; i < 44100; ++i) {
delete [] samplesIn[i];
delete [] samplesOut[i];
}
delete [] samplesIn;
delete [] samplesOut;
return 0;
}
#Constantin's answer pretty much nailed it, but I just wanted to add that in your implementation you should not allocate the buffers in your process() callback. Doing so may cause your plugin to take too much time, and as a consequence the system can drop audio buffers, causing playback glitches.
So instead, these buffers should be fields of your main processing class (ie, the AEffect), and you should allocate their size in the constructor. Never use new or delete inside of the process() method or else you are asking for trouble!
Here's a great guide about the do's and don'ts of realtime audio programming.
If you want to write something in C++ to provide a similar interface like the one you showed, I would use std::vector for managing the memory like this:
vector<vector<double>> buffers (2,vector<double>(500));
This only stores the data. For an array of pointers you need an array of pointers. :)
vector<double*> pointers;
pointers.push_back(buffers[0].data());
pointers.push_back(buffers[1].data());
This works since std::vector makes the guarantee that all elements are stored adjacent and linearly in memory. So, you're also allowed to do this:
double** p = pointers.data();
p[0][123] = 17;
p[1][222] = 29;
It's important to note that if you resize some of these vectors, the pointers might get invalid in which case you should go ahead and get the new pointer(s).
Keep in mind that the data member function is a C++11 feature. If you don't want to use it, you can write
&some_vector[0] // instead of some_vector.data()
(unless the vector is empty)
Instead of passing a double** to some function, you might be interested in passing the buffers vector directly by reference, though, this obviously won't work if you want your interface to be C compatible. Just saying.
Edit: A note on why I chose std::vector over new[] and malloc: Because it's the right thing to do in modern C++! The chance of messing up in this case is lower. You won't have any memory leaks since the vector takes care of managing the memory. This is especially important in C++ since you might have exceptions flying around so that functions might be exited early before the use of a delete[] at the end of the function.
Apologies if this is a silly question - I've been self-teaching C++ and am currently writing a memory manager as an exercise for myself, but I'm not clear on what happens under the hood when I'm calling malloc and free. I've provided some skeleton code below that hopefully illustrates my question a little better.
I have overriden the global new and delete operators to call into the Alloc(size_t) and Free(void*) methods of a MemoryManager class and have set up a few memory pools that are working very well. However, I allow one of my pools to grow when it needs to. This pool is initialized by allocating some heap memory to a pointer: char* mPoolAllocator.
My question is basically: When I grow my pool, is it safe to use the same pointer (mPoolAllocator) to allocate some new heap memory? What happens when I call free(mPoolAllocator) in ~MemoryManager() below? Does the default memory manager keep track of every bit of heap memory I've allocated using this pointer and allow me to free them all in one call to free, or is it simply freeing the block beginning at the address that the pointer was last set to?
The code below is only an illustration and is nowhere near to how my MemoryManager class works: I'm primarily looking for feedback on malloc() and free().
.....................................................................................................................................................................
class MemoryManager
class MemoryManager
{
public:
MemoryManager();
~MemoryManager();
void* Alloc(size_t size);
void Free(void* address);
private:
size_t mFreeMemory; // unallocated memory left
char* mPoolAllocator, // used to alloc memory from the heap
* mUnallocated; // points to front of free blocks linked list
void ExtendPool(); // extends pool, increasing available memory
void* GetBlock(size_t size); // returns heap address sufficient for and object of size
}
.
void* MemoryManager::Alloc(size_t size)
{
/* If there is free memory */
if(size <= mFreeMemory)
{
return GetBlock(size);
}
else // else create new free memory
{
ExtendPool();
return GetBlock(size);
}
}
.
void MemoryManager::ExtendPool()
{
mPoolAllocator = (char*)malloc(POOL_EXTEND_SIZE);
// some calls to functions that split the extended pool into blocks
mUnallocated = mPoolAllocator; // point to the next unallocated memory block (beginning of extended pool)
}
.
MemoryManager::~MemoryManager()
{
free(mPoolAllocator);
}
No, that leaks memory.
Each return value from malloc() must be used as an argument in a distinct call tofree(). For this usage, look into realloc() which will make it work more like you expect, since it allows you to grow an already-allocated piece of heap memory.
There is no trace in the mPoolAllocator variable of the previous pointers returned from malloc().
Also, in C++, shouldn't you use new[] to allocate arrays of bytes?
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 was given the assignment of making my own memory manager class, but I really have no idea where to start. My instructions are;
//1> write a memman allocation function
//2> insure the alloce functions returns unused addresses
//3> once all memman memmory is used up, subsequent alloces return NULL
//4> enable freeing of memory and subsequent reuse of those free'd regions
I've tried searching around for any guides on dealing with memory allocation, but I have not been too successful.
Here is one very, very naive idea to get you started:
char arena[1000000];
char * current = arena;
void * memman(std::size_t n)
{
char * p = current;
current += 16 * ((n + 15) / 16); // or whatever your alignment
return p;
}
All the memory is statically allocated, so you don't need any library calls to get your initial chunk of memory. We make sure to return only pointers with maximal alignment (hardcoded to 16 here, though this should be a constant like sizeof(std::maxalign_t)). This version doesn't allow for any reclamation, and it's missing the overflow checks.
For reclamation, you could try and write a free list.
As a slight variation, you could make your array be an array of maxalign_ts, which would simplify the stepping logic a bit. Or you could make it an array of uintptr_t and use the memory itself as the free list.
This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
How can I get the size of an array from a pointer in C?
Any tool to find size of memory allocated dynamically using malloc/realloc?
How can I get the size of a pointer of a segment of memory, mallocked by function malloc, if only given a pointer
???
Here is an example:
typedef struct _BlockHeader {
int Size;
} BlockHeader;
void *MyMalloc(int size) {
char *ptr = malloc(size + sizeof(BlockHeader));
BlockHeader *hdr = (BlockHeader*)ptr;
hdr->Size = size;
return (ptr + sizeof(BlockHeader));
}
void MyFree(void *ptr) {
char *myptr = (char*)ptr;
free(myptr - sizeof(BlockHeader));
}
int GetPtrMallocedSize(void *ptr) {
char *myptr = (char*)ptr;
BlockHeader *hdr = myptr - sizeof(BlockHeader);
return (hdr->size);
}
Pratically each memory block starts with an header, collecting memory block information. Of course also realloc and calloc shall be implemented, but memory block cannot be used by other software which expect "normal" malloced memory.
Another way to do this is to hash the pointer, and collect memory information by hooking the malloc/free functions.
I know that MS CRT uses this to keep track of heap overflow and memory leaks. I don't know if there are some sideeffect... actually I've never used it.
You cannot, at least not without knowing the internals of your implementations version of malloc and how it's data structure of allocated blocks looks like.
You can't. Since you allocated the memory in the first place, you're responsible for keeping track of what and how much you allocated.
You get the size of the pointer p with sizeof(p).
If you ask for the size of the memory chunk, that is used to fulfill the malloc call, this might be version specific.
There is no standard for this, so its implementation specific. On windows however, you can use _msize.