Help with memory leak (malloc) - c++

I'v followed a tutorial to use OGL tesselaton. In one of the callbacks there is a malloc and it creates a leak every time I render a new frame.
void CALLBACK combineCallback(GLdouble coords[3], GLdouble *vertex_data[4],
GLfloat weight[4], GLdouble **dataOut)
{
GLdouble *vertex;
vertex = (GLdouble *) malloc(6 * sizeof(GLdouble));
vertex[0] = coords[0];
vertex[1] = coords[1];
vertex[2] = coords[2];
for (int i = 3; i < 6; i++)
{
vertex[i] = weight[0] * vertex_data[0][i] +
weight[1] * vertex_data[0][i] +
weight[2] * vertex_data[0][i] +
weight[3] * vertex_data[0][i];
}
*dataOut = vertex;
}
I'v tried to free(vertex) but then the polygons did not render. I also tried allocating on the heap then doing delete(vertex) but then the polygon rendered awkwardly. I'm not sure what to do.
Thanks

You should call free on whatever dataOut points to. For example, if you did this from the calling function:
combineCallback (coords, vertex_data, weight, &dataOut);
then you should call free (dataOut) after you're done using it later. If you free (vertex), that effectively means whatever dataOut points to is free to be overwritten because you assigned the address of vertex to *dataOut. In other words, don't free vertex; free whatever dataOut points to.

The tool you want to look at is called valgrind, at http://valgrind.org/. That's assuming you're running on a Linux system.
As a note to readers, the "-grind" in valgrind is not related to the English word "grind".
The "Val" as in the world "value". The "grind" is pronounced with a short 'i' -- ie. "grinned" (rhymes with "tinned") rather than "grined" (rhymes with "find").

You can't free the vertex because you are assigning the memory to the dataOut object. You need to free the dataOut object once you are done with it.

I'm not sure how to fix your memory leak situation, however, one thing I would point out, is that using "delete" (I assume you meant the c++ 'delete' operator) to clean up memory that was allocated with "malloc", is highly discouraged.
Generally speaking, you need to stick with the appropriate functions for what you used to allocate in the first place. In C++ you would use 'delete' after allocating memory with 'new', and in C you would use 'free' after allocating memory with 'malloc'.

According to the docs for GLUT_TESS_COMBINE,
The user is responsible for freeing the memory some time after gluTessEndPolygon is called.
One way is to add the memory you allocate to a linked list and free it all when you're done.

You need to free the data somewhere outside this function, after you're finished using it. Without seeing the other code, it's a bit hard to guess where that will be though. You might be better off allocating the data elsewhere, and passing a pointer to it in so this can modify that other data. This is particularly true when you're likely to generate quite a bit of data (it can avoid allocating and freeing a lot of data).

Related

Find out where heap memory gets corrupted

I know there are already many similar questions and answers exist, but I am not able to solve my problem.
In my big application heap is getting corrupted somewhere and I am not able to locate it. I used tool like gflags also but no luck.
I tried gflags on the following sample which corrupts the heap by purpose:
char* pBuffer = new char[256];
memset(pBuffer, 0, 256 + 1);
delete[] pBuffer;
At line#2 heap is overwritten but how to find it via tools like gflags, windbg etc. May be I am not using the gflags properly.
If automated tools (like electric fence or valgrind) don't do the trick, and staring intently at your code to try and figure out where it might have gone wrong doesn't help, and disabling/enabling various operations (until you get a correlation between the presence of heap-corruption and what operations did or didn't execute beforehand) to narrow it doesn't seem to work, you can always try this technique, which attempts to find the corruption sooner rather than later, so as to make it easier to track down the source:
Create your own custom new and delete operators that put corruption-evident guard areas around the allocated memory regions, something like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <new>
// make this however big you feel is "big enough" so that corrupted bytes will be seen in the guard bands
static int GUARD_BAND_SIZE_BYTES = 64;
static void * MyCustomAlloc(size_t userNumBytes)
{
// We'll allocate space for a guard-band, then space to store the user's allocation-size-value,
// then space for the user's actual data bytes, then finally space for a second guard-band at the end.
char * buf = (char *) malloc(GUARD_BAND_SIZE_BYTES+sizeof(userNumBytes)+userNumBytes+GUARD_BAND_SIZE_BYTES);
if (buf)
{
char * w = buf;
memset(w, 'B', GUARD_BAND_SIZE_BYTES); w += GUARD_BAND_SIZE_BYTES;
memcpy(w, &userNumBytes, sizeof(userNumBytes)); w += sizeof(userNumBytes);
char * userRetVal = w; w += userNumBytes;
memset(w, 'E', GUARD_BAND_SIZE_BYTES); w += GUARD_BAND_SIZE_BYTES;
return userRetVal;
}
else throw std::bad_alloc();
}
static void MyCustomDelete(void * p)
{
if (p == NULL) return; // since delete NULL is a safe no-op
// Convert the user's pointer back to a pointer to the top of our header bytes
char * internalCP = ((char *) p)-(GUARD_BAND_SIZE_BYTES+sizeof(size_t));
char * cp = internalCP;
for (int i=0; i<GUARD_BAND_SIZE_BYTES; i++)
{
if (*cp++ != 'B')
{
printf("CORRUPTION DETECTED at BEGIN GUARD BAND POSITION %i of allocation %p\n", i, p);
abort();
}
}
// At this point, (cp) should be pointing to the stored (userNumBytes) field
size_t userNumBytes = *((const size_t *)cp);
cp += sizeof(userNumBytes); // skip past the user's data
cp += userNumBytes;
// At this point, (cp) should be pointing to the second guard band
for (int i=0; i<GUARD_BAND_SIZE_BYTES; i++)
{
if (*cp++ != 'E')
{
printf("CORRUPTION DETECTED at END GUARD BAND POSITION %i of allocation %p\n", i, p);
abort();
}
}
// If we got here, no corruption was detected, so free the memory and carry on
free(internalCP);
}
// override the global C++ new/delete operators to call our
// instrumented functions rather than their normal behavior
void * operator new(size_t s) throw(std::bad_alloc) {return MyCustomAlloc(s);}
void * operator new[](size_t s) throw(std::bad_alloc) {return MyCustomAlloc(s);}
void operator delete(void * p) throw() {MyCustomDelete(p);}
void operator delete[](void * p) throw() {MyCustomDelete(p);}
... the above will be enough to get you Electric-Fence style functionality, in that if anything writes into either of the two 64-byte "guard bands" at the beginning or end of any new/delete memory-allocation, then when the allocation is deleted, MyCustomDelete() will notice the corruption and crash the program.
If that's not good enough (e.g. because by the time the deletion occurs, so much has happened since the corruption that it's difficult to tell what caused the corruption), you can go even further by having MyCustomAlloc() add the allocated buffer into a singleton/global doubly-linked list of allocations, and have MyCustomDelete() remove it from that same list (make sure to serialize these operations if your program is multithreaded!). The advantage of doing that is that you can then add another function called e.g. CheckForHeapCorruption() that will iterate over that linked list and check the guard-bands of every allocation in the linked list, and report if any of them have been corrupted. Then you can sprinkle calls to CheckForHeapCorruption() throughout your code, so that when heap corruption occurs it will be detected at the next call to CheckForHeapCorruption() rather than some time later on. Eventually you will find that one call to CheckForHeapCorruption() passed with flying colors, and then the next call to CheckForHeapCorruption(), just a few lines later, detected corruption, at which point you know that the corruption was caused by whatever code executed between the two calls to CheckForHeapCorruption(), and you can then study that particular code to figure out what it's doing wrong, and/or add more calls to CheckForHeapCorruption() into that code as necessary.
Repeat until the bug becomes obvious. Good luck!
If the same variable is consistently being corrupted, data break points are a quick and simple way to find the code responsible for the change (if your IDE supports them). (Debug->New Break Point->New Data Breakpoint... in MS Visual Studio 2008). They won't help if your heap corruption is more random (but figured I'd share the simple answer in case it helps).
There's a tool called electric fence that I think is supported also on Windows.
Essentially, what it does is hijack malloc and co to make every allocation end at page boundary and mark the next page inaccessible.
The effect is that you get a seg fault on buffer overrun.
It probably also have an option for buffer underrun.
Please read this link
Visual Studio - how to find source of heap corruption errors
Is there a good Valgrind substitute for Windows?
It tells technique for finding heap issues on windows.
But on the other hand you can always write (if you are writing new code) memory managers.
The way to do is: use your wrapper apis which will call malloc/calloc etc.
Suppose you have api myMalloc(size_t len);
then inside your function, you can try allocationg HEADER + len + FOOTER.
On your header save info like size of allocation or may be more info. At the footer, add some magic number like deadbeef. And return ptr(from malloc) + HEADER from myMalloc.
When freeing it up using myfree(void *ptr), then just do ptr -HEADER, check the len, then jump at the FOOTER = ptr-HEADER + really allcated len. At this offset, you should find deadbeef, and if you dont find, then you know, its been corrupted.

Is it possible to resize/reallocate a large chunk of memory without invalidating pointers?

I'm working on an Allocator system for my game engine and I'm wonder if it is possible to reallocate memory (multiple of PageSize) without invalidating the pointers that point to locations within it. Can this be accomplished using a virtual memory interface? I'm aware virtual memory paging doesn't work for DMA/pinned memory, and that its not available on consoles.
Is realloc able to do this(but not guarantee it)? I'm looking for a POSIX, Linux, or Windows api that can do this just so I have a place to start.
Also, I would appreciate any further readings relevant to creating a memory management system, thanks.
The virtuality of the address space is not all that relevant to your proposed solution. The reason a larger block may not be possible is because there is data in the address space that you want your array to grow into. This is the same problem on physical and virtual memory spaces.
I can see two alternative approaches.
There are two easy approaches. First, reserve enough memory in a std::vector. This does should do nothing but aquire virtual memory space on efficient systems. Grow it as needed, and those virtual memory pages will be assigned physical pages. This is more practical on 64 bit systems, as you have a huge memory space.
Another approach would be to create your own segmented like array. Have a vector with unique pointers to page sized chunks, and a wrapper that hides that detail. This adds another layer of indirection on iterator access. Implementing fast-blit for trivially copiable types and other operations optional.
If there's a particular allocation that you're especially keen to keep in-place, it may make sense to malloc much more memory than initially needed. On a modern OS, that will reserve virtual address space - which will be effectively unconstrained for any 64-bit app - and actual physical backing memory will only be sought as pages are first accessed, so an excessive initial allocation is extremely "low cost" but may prevent a need to realloc beyond that size. That's much easier for you than fiddling with or replacing the allocation routines....
If you have a great many allocations, and/or a 32-bit app, you may want to pursue the ability to:
ask realloc if it can operate in-place (e.g. adding an extra function argument to prevent moving to another address and returning nullptr when it fails); this approach reduces pointer adjustments without necessarily being more aggressive in allocating virtual address space, but you'll still need to handle having to move sometimes; and/or
intercept malloc and realloc calls and allocate them much more virtual address space than requested to reduce (or - given application specific knowledge - eliminate) the risk of needing to move the content during a later realloc.
The Standard-mandated malloc/free/realloc interface has no hooks or options for reallocating only if in-place (and letting you know when it "fails"), so you will need to write your own routines or edit a malloc-et-al library.
Without writing your own allocator, or adopting a third-party one, there is no way to grow a malloc'ed block and guarantee that it doesn't move. Realloc may move it and there's no way to force it to fail if it can't grow in place.
You might want to look into std::deque. It is like a std::vector in many respects (a growable memory array), but when elements are added, it does not ever reallocate storage for old elements or move the existing objects in memory. It does have some downsides--there's no guarantee that all the objects will be contiguous in memory, and accessing an element of the deque is slightly slower than accessing a vector element, as it has to first calculate which block the object is in, then calculate the location of the element within the block. Generally this should not make a noticeable difference unless it is extremely performance critical.
Well, since you are writing it in c++:
overload malloc()/realloc()/free() with specialized versions
instead of using bare pointers, use a special class, say class myptr which
When dereferenced doesn't do anything extra, just dereferences
When assigned, adds the variable to a list which realloc() looks through to repoint any pointers needing adjustment.
The weakness of this is that unless are very few types of objects being pointed to, it might be tedious to get the types to simply work. Of course, that is a suitable task for templates...
Here is some code that does what you asked for. If realloc() moves the block of memory, then it finds and fixes the pointers into and within the block. This was inspired by the BDWGC project, but they are not to blame. The danger with this code is it will find a word in memory that looks like a pointer but is not a pointer.
struct dbbExprAllocFixup {
typedef dbbExpr * dbbExprPtr;
dbbExprAllocFixup( void *, size_t, void * );
void CheckExpr( dbbExprPtr & );
void CheckOne( void *, char * tag );
void CheckRange();
char * oldBase; // old realloc() ptr
char * oldEnd;
char * newBase; // new realloc() ptr
char * newEnd;
ptrdiff_t delta;
};
dbbExprAllocFixup::dbbExprAllocFixup( void * ob, size_t ns, void * nb )
{
oldBase = (char *) ob;
oldEnd = oldBase + ns;
newBase = (char *) nb;
newEnd = newBase + ns;
delta = newBase - oldBase;
dbbTrace::Output( "Expr realloc: (%p to %p) moved to %p, delta = %p\n",
oldBase, oldEnd, newBase, delta );
}
void
dbbExprAllocFixup::CheckOne( void * p, char * tag )
{
char * * scan = (char * *) p;
char * value = * scan;
if( value >= oldBase && value <= oldEnd ) {
// This value needs fixing
* scan = * scan + delta;
dbbTrace::Output( " Expr realloc: %s old value %p new value %p\n",
tag, value, * scan );
}
}
void
dbbExprAllocFixup::CheckExpr( dbbExprPtr & p )
{
if( p != 0 ) {
CheckOne( & p, "e" );
}
}
void
dbbExprAllocFixup::CheckRange()
{
char * * scan;
for( scan = (char * *) newBase; scan < (char * *) newEnd; scan++ ) {
CheckOne( scan, "r" );
} // for
}
The code that calls realloc() and dbbExprAllocFixup if needed.
void * p = ::realloc( m_pHead, bytes );
if( p == m_pHead ) {
// The memory did not move, do nothing
} else {
// The memory moved
dbbExprAllocFixup f( m_pHead, bytes, p );
// Fix pointer in the block to locations in the block
f.CheckRange();
// Fix pointers outside the block that point into the block
f.CheckExpr( pExpr->m_pRoot );
for( int i = 0; i < pExpr->m_MLRootSize; i++ ) {
f.CheckExpr( pExpr->m_pMLRoot[i] );
}
m_pHead = (dbbExprAllocChunk *) p;
} // if
This code is not in use so could easily have bugs. One bug I noticed now is it uses the new size for both the old and new realloc() memory blocks.

How to know if two C-strings point to one memory block?

I have an array allocated with malloc:
char *aStr1 = (char* ) malloc (10);
And then I filled this memory:
strcpy(aStr1, "ABCDEFGHI");
After that I created a new pointer aStr2:
char *aStr2 = aStr1 + 5;
And i set fourth element of memory to '\0':
*(aStr1 + 4) = '\0';
And finally, using these two pointers in a simple function:
int checkMem(char *aStr1, char *aStr2);
This function returns true (some none zero value) if aStr1 and aStr2 pointed to one memory block, and returns zero in another case.
How i can implement this function? (I read many linux mans about allocs function and haven't found any information about such problem).
//Added
I need this to do something like that:
char *aStr1 = (char *) malloc (10);
char *aStr2 = aStr1 + 5;
strcpy(aStr1, "ABCDEFGHI");
*(aStr1 + 4) = '\0';
and than:
my_strcat(aStr1, aStr2);
I do not ask for help to implement my_strcat, but maybe, get some hint how i can resolve its problem
//Updated
thanx, for all. I solved it.
Without any low level functions you cannot correctly know, how many memory allocate (maybe on some platform or realization you can do this:
size_t ptr_size = *((size_t *)ptr - 1);
but maybe not for all it will be correct).
And solving is simple: i create local copy of aSrc2, then realloc aSrc1 and copy aSrc2 to new aSrc1.
Unfortunately you cannot tell if two pointers point to memory that belonged to the same initial allocation.
You can create classes/structures that, for instance, save the initial allocation and then you could compare them.
But without added information, you simply cannot tell.
There is no provided standard mechanism for doing this, its up to you to track the memory you received and how big those allocations are, so you'd probably want to provide your own malloc wrapper that tracks what's allocd. Store the pointers in a map so you can use lower_bound to find the nearest allocate to the first string and then check if the second string is in the same allocation.

How to create pointer to pointer array same as VST audio buffer?

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.

Writing my own memory manager class, overriding new and delete operators

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.