Jump to content
  • Advertisement
Sign in to follow this  
j0mm0noer

low level memory access in C++ - structures, pointers, malloc / new etc!

This topic is 3351 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

I am trying to directly access memory in C++, in order to quickly read and store values. A small test program is as follows: nt setup_objectdata ( ) { int* buffer = new int[1024]; *(buffer) = 12; 12 polygons in this object *(buffer + 4) = 16; // 16 vertices in this object *(buffer + 8) = 2.65f // x bounding box start // etc etc. return *buffer; } Obviously, this will not work. The buffer has to be set up as a particular datatype (in this case integers), and now I am trying to store a float there. It would not even compile if I was using 'char' as the way to reserve my memory. What I want to do is to be able to reserve a block of memory, then read + write ints and floats at will from it, assuming both are using 4-bytes each. The data (ints and floats) in the memory will change slightly depending on the object, number of polygons / quads / triangles / lines / points, so there is no defined structure for the data within the memory block. One idea I tried was to define this structure: struct subobject { float xoffset; float yoffset; float zoffset; int number_of_polygons; int polygon_type_first_polygon; int pointer_to_polygon_linked_list; }; The idea was to make a POINTER to a structure like this, and then point that pointer to (buffer+0), but I can't get that to work. I would then need seperate structs to read all the different polygon types etc! It seemed a long-winded way to allow the freedom you would get with assembly language or BASIC, but I can't seem to get that to work anyway. So, I ask : how do I do what I am trying to do in the first code example? (reserve a block of memory, and then read and write, arbitarily, floats, ints, (or chars) etc from that?) (I might even want to store an int, then read it back as a float). Is this possible in C++ in a simple way? Thanks for the help! :)

Share this post


Link to post
Share on other sites
Advertisement

char* pBuffer = new char[ 1024 ]; // 1 kb of memory..

char* pCurrent = pBuffer;

// write a float:
*( (float*)pCurrent ) = 3.14159265f;
pCurrent += sizeof( float );

// write a int:
*( (int*)pCurrent) ) = 42;
pCurrent += sizeof( int );

// write a big pod struct:
Polygon poly;
memcpy( pCurrent, &poly, sizeof( poly ) );
pCurrent += sizeof( poly );

// ....



Additional tip: You probably should write helper functions (writeFloat, writeInt, writeXXX) that check if the buffer has enough space left for the data. (And it would make the code more readable).

something like this;

struct Buffer
{
char* pCurrent;
char* pEnd;
};

void writeInt( Buffer& buffer, int value )
{
if( buffer.pEnd - buffer.pCurrent >= sizeof( int ) )
{
*( ( int* )buffer.pCurrent ) = value;
buffer.pCurrent += sizeof( int );
}
else
{
// error handling..
}
}


Cheers
Julien

Share this post


Link to post
Share on other sites
Maybe something like this would work for you

class Buffer
{
public:
// you have to add constructor/destructor and resize stuff yourself
// and i didn't test this code so there might be typos or w/e
template<typename T> T Read()
{
T* pValue = *reinterpret_cast<T*>(m_buf+m_seekPos);
m_seekPos += sizeof(T);
return *pValue;
}
template<typename T> void Write(const T& value)
{
*reinterpret_cast<T*>(m_buf+m_seekPos) = value;
m_seekPos += sizeof(T);
}
private:
unsigned char* m_buf;
size_t m_seekPos;
};


eventually you could also use memcpy, especially if you want to avoid unaligned memory access..

edit: someone ninja posted before me :/

Share this post


Link to post
Share on other sites
WTF? I'm trying to get a better understanding of what you're trying to accomplish here. It looks to me that you're vastly over complicating something. What are you trying to accomplish at a higher level? I have a hunch that you're taking the wrong approach here.

[Edited by - Wolfdog on October 11, 2009 4:01:10 AM]

Share this post


Link to post
Share on other sites
Quote:
Original post by j0mm0noer
The data (ints and floats) in the memory will change slightly depending on the object

That's what polymorphism exists for.

Share this post


Link to post
Share on other sites
Hey j0mm0noer,
I havent read all replys to your question, but reading your first post, I think a union might do the trick.

union uData
{
int i;
float f;
};




Now you can access the int or float as you wanted and read and write to the float or int as you wish.
Of course you can allocate that also as a buffer as you did in your source example.

I think the answer is a little too trivial that you wouldnt have come of it yourself. But if you didnt this might do it

Regards Woltan

Share this post


Link to post
Share on other sites
Quote:
Original post by DevFred
Quote:
Original post by j0mm0noer
The data (ints and floats) in the memory will change slightly depending on the object

That's what polymorphism exists for.


polymorphism is the ability of one type, A, to appear as and be used like another type, B.

That has not much to do with something like the problem the original poster describes.

Cheers
Julien

Share this post


Link to post
Share on other sites
Seriously,

"
int* buffer = new int[1024];
*(buffer) = 12; 12 polygons in this object
*(buffer + 4) = 16; // 16 vertices in this object
*(buffer + 8) = 2.65f // x bounding box start
"

Won't be faster than, say:

struct myobject
{
int polygons;
int vertices;
float boundingbox_x;
};

In fact it might be slower. You are wasting your time on a nonexisting problem buddy!

Share this post


Link to post
Share on other sites
I think the original poster wants to write different data depending on data that has been written earlier.

Quote:

I would then need seperate structs to read all the different polygon types etc..


Cheers
Julien

Share this post


Link to post
Share on other sites
Quote:
Original post by j0mm0noerSo, I ask : how do I do what I am trying to do in the first code example? (reserve a block of memory, and then read and write, arbitarily, floats, ints, (or chars) etc from that?) (I might even want to store an int, then read it back as a float). Is this possible in C++ in a simple way?


If I were you, I'd go with pablo24's template-based approach. Note that if you try to read an int from a position where a float was written, you're likely to get garbage, and NOT the integer part of the float value. Also, if you will ever store objects in the buffer that need a deep copy, you should stay far, far away from memcpy().

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!