Click to See Complete Forum and Search --> : Statically allocated buffer area!


Jiang_Go
September 14th, 2002, 12:16 AM
Hi,

If I want to allocate a buffer within stack. but it seems the popular command new is useless since it allocates the memory from heap dynamically. Do you guys know something about that!

Thanks!

Jinag:confused:

stober
September 14th, 2002, 12:49 AM
If you know the size of the buffer:

int foo()
{
char buffer[BUFFER_SIZE];

// your code here
}


There is another way to dynamically allocate from the stack, but I've never used it. Look in MSDN for HeapAlloc(). It hints that you can allocate memory from any heap -- and the stack is just another type of heap. Personally, I don't think the stack heap should ever be used for that purpose becuase it is too easy to screw up your entire program.

Jiang_Go
September 14th, 2002, 01:50 AM
Hi,

Sorry, maybe I do not state my question clearly, I want to find a way to statically allocate some memory from stack! NOT DYNAMICALLY. That means the address of such buffer should be fixed in the program!

Anyway, thank you for your reply!

Jiang

stober
September 14th, 2002, 01:54 AM
That's impossible because the stack cannot be used for that purpose! The best you can do his this:

int foo()
{
static buffer[BUFFER_SIZE];
}

cup
September 14th, 2002, 03:05 AM
You could try this syntax but it will only work on the newer compilers and you must remember never to delete it.

class Fred
{
// whatever
};
main ()
{
char buffer[ /* whatever size you wish */];

// Create derf on the stack in buffer
Fred* derf = new (buffer) Fred;

...

// deleting derf will cause a crash!!!
return 0;
}

Alternatively, there is a C routine called alloc (Solaris) or _alloca (Microsoft) which will allocate memory from the stack.

stober
September 14th, 2002, 06:46 AM
Originally posted by cup
[B]You could try this syntax but it will only work on the newer compilers and you must remember never to delete it.

class Fred
{
// whatever
};
main ()
{
char buffer[ /* whatever size you wish */];

// Create derf on the stack in buffer
Fred* derf = new (buffer) Fred;

...

// deleting derf will cause a crash!!!
return 0;
}



That does not work with VC6 compiler -- "error C2660: 'new' : function does not take 2 parameters"

cup
September 14th, 2002, 08:56 AM
That's strange because the following works on VC++ SP0

#include <iostream>
using namespace std;
class Fred
{
public:
int subkey1;
int subkey2;
Fred ()
: subkey1(0)
, subkey2(0)
{
}

void Dump ()
{
cout << "Fred " << subkey1 << " " << subkey2 << endl;
}

};

main ()
{
char buffer[100];
Fred* derf = new (buffer) Fred ();
derf->subkey1 = 100;
derf->Dump ();
return 0;
}

stober
September 14th, 2002, 11:44 AM
I copied your code and it compiles ok for me in VC6 too. I must have done something wrong.

stober
September 14th, 2002, 12:06 PM
When you do that, you must insure that the alignment of the objects allocated that way are correct. The new (buffer) operator simply returns a pointer to buffer and makes no alignment checks or check to see if it has already been allocated to something else.

There are other major problems with this approach too. You can not use the delete operator to deallocate Fred because it wasn't really allocated in the first place. That means the destructor is never called, which could create a lot of memory leaks.


main ()
{
char buffer[255];
Fred* derf = new (buffer) Fred ();
Fred* derf1 = new (buffer + sizeof(Fred)) Fred ();
if(derf == derf1)
cout << "they are the same" << endl;
else
cout << "they are different." << endl;
derf->subkey1 = 100;
derf->Dump ();
return 0;
}

cup
September 15th, 2002, 01:01 AM
Yup - you're right there. I normally use it for PROM based stuff or memory mapped files where the memory is at a fixed address and there is only one structure and no pointers.

The only other way I know of is to use alloc (Solaris) or _alloca (MS) and cast it. Again, with this one, you musn't use free. It also boils down to a similar thing but this time, since it is an alloc, there is no new or delete. It gets worse:)

JamesSchumacher
September 15th, 2002, 03:09 PM
There is a corresponding placement delete to the placement new.

And you can overload those types as well.

For placement new and new[]

void * __cdecl operator new(unsigned int nSize,void * pAddress) throw()
{
return pAddress;
}

void * __cdecl operator new[](unsigned int nSize, void * pAddress) throw()
{
return pAddress;
}

placement delete and delete[]

void __cdecl operator delete(void * pBuf,void * pAddress) throw()
{

}

void __cdecl operator delete[](void * pBuf, void * pAddress) throw()
{

}

cup
September 15th, 2002, 04:36 PM
Another alternative is to use C#. In C#, classes are instantiated on the heap and structs on the stack.

Plastelin
September 16th, 2002, 05:50 AM
there is one old command:
"_alloca"
to allocate memory on stack, and you do not have to free it, it will be freed after you exit the function! :)