🔒 Locked
Pointer table
Advertisement
Original Post
Hi, justa a quick quesion, I want to reate a pointer table, or I guess an array of pointers, but each pointer could be to any possible object, (not specifically an int, float etc). Lets say I have an address of a variable how can I store it in a pointer table. Thanks
It is legal to use a void* array, for example:
Now, whether it is moral to do that is a totally different question [smile]
At the very least I'd say I see no reason (though you probably have one...) why one would want to store completely unrelated objects in the same array.
If the objects to store have somthing in common, you had better use a "something*" instead of a "void*". If you give more specific details about your problem, some people may be able to give you much better advice.
Edit: beaten, as usual... ;)
JA
std::vector<void*> pointerArray;// or:void* pointerArray[WHATEVER_SZIE];// thenpointerArray[0] = static_cast<void*>(whateverPointer);Now, whether it is moral to do that is a totally different question [smile]
At the very least I'd say I see no reason (though you probably have one...) why one would want to store completely unrelated objects in the same array.
If the objects to store have somthing in common, you had better use a "something*" instead of a "void*". If you give more specific details about your problem, some people may be able to give you much better advice.
Edit: beaten, as usual... ;)
JA
You can bust out the void**, but it's dangerous!
This is scary though because you may not know how to cast each table entry to retrieve something meaningful. If you are using C++ it would be better to use std::vector like the poster above.
void **table = malloc(sizeof(void*) * TABLE_SIZE);int a = 10;float b = 20;table[0] = (void*)(&a);table[1] = (void*)(&b);printf("a = %d\n", *((int*)table[0]));printf("b = %f\n", *((float*)table[1]));free(table);This is scary though because you may not know how to cast each table entry to retrieve something meaningful. If you are using C++ it would be better to use std::vector like the poster above.
Thanks for fast responses guys, I want to use the table in a resource manager for my game. When I would call LoadItemFromFile() I would load a specified item into ram ( by saying "address" = new "type"; ) address will now be the pointer to that object that I just allocated. I will store the pointer in a table, and return the items ID to the user. Then he would call GetItemById(int ID), the ID will simply be the offset into the pointer array (like janta suggested), and the user will get the pointer to whatever he wants.
edit: the Items i could load into ram with LoadItemFromFile() could be anything, images, meshes, cameras etc, thats why I need a table of diverse types, if theres a better way please let me know.
edit: the Items i could load into ram with LoadItemFromFile() could be anything, images, meshes, cameras etc, thats why I need a table of diverse types, if theres a better way please let me know.
I could suggest you a slightly different scheme, while still very simple (since you seem to be looking for something very simple, right?)
I guess the number of different "type" of resources is rather limited (like less than 16 or so)
Instead of having a Resource ID that is just an index, you could have a resuorce ID that is a DWORD which 8 lowest bits represents the resource type and the remaining 24 bits represents the resource index in the array.
Then instead of one big array you could have one array for each type of resource.
I think that would at least be an improvement of you current system.
JA
I guess the number of different "type" of resources is rather limited (like less than 16 or so)
Instead of having a Resource ID that is just an index, you could have a resuorce ID that is a DWORD which 8 lowest bits represents the resource type and the remaining 24 bits represents the resource index in the array.
Then instead of one big array you could have one array for each type of resource.
I think that would at least be an improvement of you current system.
JA
Quote:
Original post by janta
I could suggest you a slightly different scheme, while still very simple (since you seem to be looking for something very simple, right?)
I guess the number of different "type" of resources is rather limited (like less than 16 or so)
Instead of having a Resource ID that is just an index, you could have a resuorce ID that is a DWORD which 8 lowest bits represents the resource type and the remaining 24 bits represents the resource index in the array.
Then instead of one big array you could have one array for each type of resource.
I think that would at least be an improvement of you current system.
JA
I thought about that, and thats exactly what I was trying to avoid, game resources are not that small, so for example my Mesh class takes up quite a bit of mem, not to mention the GUI sprites, Camera classes which are also big, maybe Music etc. If I have an indefinite array of each, like if im using std::vector then im bound into running into problems. Also that sort of hardcodes all the types into the RManager, which reduces flexibility if I want to add new resource types.
The way you organize you pointers and the footprint of the memory these pointers point to are two different things. If you load 100 meshes, then the memory used is pretty much the same whether you store these 100 Mesh* in a separate array or in the same array as all other resource type, right ? So I dont understand why you think you'd be running into problems.
Off hand, the way I suggested gives some advantage:
- resource ID carry actual information about the type of resource they represent
- No two resources of different type could ever have the same ID (and that should save you from a lot of bugs IMHO)
- Resource management will be a little bit more efficient since you'd be
- Iterating over a given type of resource will be easier
Off hand, the way I suggested gives some advantage:
- resource ID carry actual information about the type of resource they represent
- No two resources of different type could ever have the same ID (and that should save you from a lot of bugs IMHO)
- Resource management will be a little bit more efficient since you'd be
- Iterating over a given type of resource will be easier
Quote:
Original post by janta
The way you organize you pointers and the footprint of the memory these pointers point to are two different things. If you load 100 meshes, then the memory used is pretty much the same whether you store these 100 Mesh* in a separate array or in the same array as all other resource type, right ? So I dont understand why you think you'd be running into problems.
Why is it the same? If I load a lets say I load a mesh from a filename, so I say
Mesh Car = new Mesh; that would allocate the sizeof(Mesh) on the stack. And if I have another Mesh m_pMesh[10]; in my RManager class, that would mean that im allocating 10*sizeof(Mesh) on the stack, so I wouldn't that double the mem that I'm using. I guess if I create an array of mesh pointers then It would work. I might be mistaken thought, correct me if im wrong.
Quote:
As i see it, the way I suggested gives some advantage, off the TOMH:
- resource ID carry actual information about the type of resource they represent
- No two resources of different type could ever have the same ID (and that should save you from a lot of bugs IMHO)
- Resource management will be a little bit more efficient since you'd be
- Iterating over a given type of resource will be easier
But again even If I do incorporate the resources into the RM class, I would be breaking logical cohesion, meaning I the routine would no longer be doing one thing and one thing only, but now the RM class would depend on the Mesh, Camera, Sound, Sprite classes. It would also make it more heavy. Even it is possible to store the resources here without a performance cost, I'd rather allow the caller of the manager deal with the resource and store it wherever it wants. Then all this class would be doing would be allocating/deleting and keeping a list of addresses of the functions that it created so far. Thats how the OSs keep the tread tables, and function tables.
Quote:
Resource management will be a little bit more efficient since you'd be
- Iterating over a given type of resource will be easier
But If i have a single list with all the resources that i created, I don't particularly have to know whcih resources are of which type, since I can categorize them as simply "resource". I think its clearer that way.
Another method (which does have some problems and still requires type conversion) is to derive all your resources from a resource class, eg CResource.
That way you can have an array or vector of CResource*. That way you can clean up your resources safely by simply looping through the array or vector calling delete on all the pointers.
You could even create an enum value for each resource type which you could use to verify a resource is of a specific type before casting.
So your resource type and a string type might look like.
However, I still think a separate vector or array for each separate resource type is best.
std::vector g_textures;
std::vector g_sample;
etc
note: "stack" is temporary memory used by the functions. "heap" is where your objects will be allocated. Stack memory usage is virtually never an issue.
Each void* only takes 4 or 8 bytes or so (depends on the address bus width), so your heap memory usage will not change much. If you have an array of 1000 CMesh* types and only use 50 of them, your memory will be sizeof(void*) * 1000 + sizeof(CMesh) * 5. Say your mesh is 1000 bytes and your void* is 4, this is 4000 + 50000 = 54000 bytes used (plus allocation overhead, say +50% estimate).
But I guess someone will have replied before me anyway.
That way you can have an array or vector of CResource*. That way you can clean up your resources safely by simply looping through the array or vector calling delete on all the pointers.
You could even create an enum value for each resource type which you could use to verify a resource is of a specific type before casting.
So your resource type and a string type might look like.
class CResource { public: virtual ~CResource() {} bool verify(int type) { return m_resource_type == type; } protected: CResource(int type) : m_resource_type {} private: int m_resource_type;};class CString : CResource { public: CString(std::string string) : CResource(RESOURCE_IS_STRING), m_string(string) {}; ~CString() {}; std::string m_string;};However, I still think a separate vector or array for each separate resource type is best.
std::vector
std::vector
etc
Quote:
Why is it the same? If I load a lets say I load a mesh from a filename, so I say
Mesh Car = new Mesh; that would allocate the sizeof(Mesh) on the stack. And if I have another Mesh m_pMesh[10]; in my RManager class, that would mean that im allocating 10*sizeof(Mesh) on the stack, so I wouldn't that double the mem that I'm using. I guess if I create an array of mesh pointers then It would work. I might be mistaken thought, correct me if im wrong.
note: "stack" is temporary memory used by the functions. "heap" is where your objects will be allocated. Stack memory usage is virtually never an issue.
Each void* only takes 4 or 8 bytes or so (depends on the address bus width), so your heap memory usage will not change much. If you have an array of 1000 CMesh* types and only use 50 of them, your memory will be sizeof(void*) * 1000 + sizeof(CMesh) * 5. Say your mesh is 1000 bytes and your void* is 4, this is 4000 + 50000 = 54000 bytes used (plus allocation overhead, say +50% estimate).
But I guess someone will have replied before me anyway.
Quote:
Original post by VanillaSnake21
Why is it the same? If I load a lets say I load a mesh from a filename, so I say Mesh Car = new Mesh; that would allocate the sizeof(Mesh) on the stack. And if I have another Mesh m_pMesh[10]; in my RManager class, that would mean that im allocating 10*sizeof(Mesh) on the stack, so I wouldn't that double the mem that I'm using. I guess if I create an array of mesh pointers then It would work. I might be mistaken thought, correct me if im wrong.
As you said, you'd be working with pointers here (and in C++, new returns a pointer, so are you confusing with Java, or was that just a typo?)
You'd have something like this:
void ResourceManager::AllocateMesh(){ int id = pMeshes->GetFreeSlot(); // get a free index in the mesh array m_pMeshes[id] = new Mesh;}So anyways you're going to spend "sizeof(Mesh)" for the mesh itself, plus "sizeof(void*)" for the pointer that tells you where your mesh is (in memory) Whether you have 100 void* in one array or 10 void* in 10 different arrays is equivalent in term in memory, and doesnt matter anyways since the size of a pointer (usually 4 bytes) is orders of magnitudes smaller than the memory footprint of a mesh (roughly -- say -- 500 vertices = 500 * 3 floats = 6000 bytes, and I'm being very, very optimistic here)
Quote:
Original post by shukapi
Another method (which does have some problems and still requires type conversion) is to derive all your resources from a resource class, eg CResource.
That way you can have an array or vector of CResource*. That way you can clean up your resources safely by simply looping through the array or vector calling delete on all the pointers.
Thats a pretty good idea I didnt think about it, that would help me a lot during cleanup and is also more elgant. Thanks!!
Quote:
by janta
As you said, you'd be working with pointers here (and in C++, new returns a pointer, so are you confusing with Java, or was that just a typo?)
You'd have something like this:
void ResourceManager::AllocateMesh()
{
int id = pMeshes->GetFreeSlot(); // get a free index in the mesh array
m_pMeshes[id] = new Mesh;
}
Wait Im a little confused, assuming i declared m_pMeshes as
Mesh m_pMeshes[10];
so isn't m_pMeshes[index] the same as dereferencing a pointer? So when I say m_pMeshes[2], im infact referencing the third mesh object, not its pointer. So would "pMeshes[id] = new Mesh;" still work, since like you said new returns an address?
Quote:
Original post by VanillaSnake21
Wait Im a little confused, assuming i declared m_pMeshes as
Mesh m_pMeshes[10];
so isn't m_pMeshes[index] the same as dereferencing a pointer? So when I say m_pMeshes[2], im infact referencing the third mesh object, not its pointer. So would "pMeshes[id] = new Mesh;" still work, since like you said new returns an address?
In the way I understand things, you'd declare "Mesh* m_ppMesh[10]" (maybe adding that second "p" will cause you less confusion), or, much better, a "std::vector
That is, you declare an array of POINTER-TO-MESH, not an array of MESH.
Quote:
Original post by janta Quote:
Original post by VanillaSnake21
Wait Im a little confused, assuming i declared m_pMeshes as
Mesh m_pMeshes[10];
so isn't m_pMeshes[index] the same as dereferencing a pointer? So when I say m_pMeshes[2], im infact referencing the third mesh object, not its pointer. So would "pMeshes[id] = new Mesh;" still work, since like you said new returns an address?
In the way I understand things, you'd declare "Mesh* m_ppMesh[10]" (maybe adding that second "p" will cause you less confusion), or, much better, a "std::vector"
That is, you declare an array of POINTER-TO-MESH, not an array of MESH.
Alright, thanks, so it's still a pointer table, but with separate tables for eahc type of resource, Thanks a lot everyone, now I have at least 3 methods that I can ponder over. :]
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement