How to 'insert' a value into a memblock...

Started by
14 comments, last by ZealousEngine 16 years, 11 months ago
Up to this point I havent touched 'memblocks' (I have experience with them, just not in C++), but im trying to implement a message passing system like the one described here (at bottom)... http://www.gamedev.net/reference/articles/article1930.asp ...so I need to allocate a big chunk of memory, which can store a variety of undefined message types. Can anyone explain how I can do something like this...
Quote: void* ptr = malloc( 256 ); ptr[0] = someFloat; ptr[4] = anotherFloat; //then look them up float* ptrToMyFloat = static_cast<float*>(ptr[0]); float* ptrToMyOtherFloat = static_cast<float*>(ptr[4]);
...and again, I am well aware of the dangers. Like I said, I have experience with this stuff, I am just unaware of the 'proper' syntax for C. Thanks! [Edited by - ZealousEngine on May 17, 2007 7:13:28 PM]
Advertisement
instead of:

ptr[0] = someFloat;


do

memcpy( &ptr[0], someFloat, sizeof(float) );



to access...

ptr[0] actually contains your float data. so a pointer to your float data will be &ptr[0]
//just add a & before ptr[0]float *ptrToMyFloat = static_cast<float*>(&ptr[0]);


-me
Ok cool thanks.

So malloc, memcpy, ect.. are the way to do it? There is no 'more proper' c++ way? This looks fine, just want to make sure.
Quote:Original post by ZealousEngine
Ok cool thanks.

So malloc, memcpy, ect.. are the way to do it? There is no 'more proper' c++ way? This looks fine, just want to make sure.


oh. I missed the malloc. instead of malloc it should be:

void *ptr = new void*[256];


then to release the memory
delete[] ptr;


-me
Cool thanks again bud!
Akk nevermind, having some trouble. The following works fine...

Quote:
memcpy( ptr, &someFloat, sizeof(float) );


..but the following generates an error..

Quote:
memcpy( &ptr[0], &someFloat, sizeof(float) );

// error C2036: 'void *' : unknown size


Can you really use [] on a void pointer?
hrm... since you're just casting anyway, try making the buffer of type int instead of void* and see if that fixes the problem. I'd thought you should be able to use [] with void*, but maybe I'm just wrong...

-me
Well an int is 4 bytes isnt it? Wont that be a problem?

* well I tried...

Quote:
char* ptr = new char[256];
memcpy( ptr[0], &someFloat, sizeof(float) );


..but now im getting..

Quote:
error C2664: 'memcpy' : cannot convert parameter 1 from 'char' to 'void *'
It's usual to use char* buffers for this sort of thing, because sizeof(char) == 1, by definition.

Also, '&arr[x]' is equivalent to 'arr + x', which is generally considered neater.

Also, in C++, instead of using memcpy(), use std::copy from <algorithm>:

template <typename T>void appendToBuffer(char* buffer, int& position, const T& toAppend) {  char* ptrToAppend = reinterpret_cast<char*>(&toAppend);  std::copy(ptrToAppend, ptrToAppend + sizeof(T), buffer + position);  position += sizeof(T);}// Sample - append an array of floats to a buffer:int pos = 0;char buffer[10 * sizeof(float)];float f[10];for (int i = 0; i < 10; ++i) {  appendToBuffer(buffer, pos, f);  // Because 'pos' is passed by reference, it gets implicitly updated each  // time through the loop.}


Better yet, we could wrap the buffer and position up in a class. Oh, and we could use std::vector<char> for the buffer instead and avoid all that nasty memory management ;) (The 'position' is then implicitly the .size() of the vector, too, so we even save that bit of work.)

class Buffer {  std::vector<char> storage;  public:  // Note how this is designed for chaining, by returning a reference to self.  template <typename T>  Buffer& append(const T& t) {    const int pos = storage.size();    const int size = sizeof(T);    storage.resize(pos + size);    char* ptrToAppend = reinterpret_cast<char*>(&t);    std::copy(ptrToAppend, ptrToAppend + size, storage.begin() + pos);    return *this;  }};// somewhere else...float x, y, z;Buffer b;b.append(x).append(y).append(z);
Cool.. a neat tidy 'buffer' class. Are you sure it wont hurt performance in anyway? I dont have much experience with 'reinterpret_cast', ect... Also it seems like resizing the vector could be slower than pre allocating a big chunk of memory..

*Ok well I see reinterpret cast is supposed to be the 'least safe', so I assume that also means the 'fastest' as well :p. And I guess I could modify the class to only resize the buffer if the new append wont have enough room (I plan on resetting, and reusing the buffer every frame, so I dont want to be constantly resizing it).

[Edited by - ZealousEngine on May 17, 2007 8:48:24 PM]

This topic is closed to new replies.

Advertisement