Jump to content
  • Advertisement
Sign in to follow this  

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

This topic is 4023 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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]

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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?

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites
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 *'

Share this post


Link to post
Share on other sites
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);

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!