Dynamic string array problems

Started by
5 comments, last by xEricx 18 years, 10 months ago
I'm trying to store a list of the names of my textures as I load each texture, but for some reason I'm having problem with the array. The idea is I pass my texture loading function the file name, a pointer to the existing list of texture IDs, the number of textures added so far, and a pointer to the existing list of texture names (stored as strings). Each time the function is called, the first thing it does is call realloc on both the list of texture IDs and the list of texture names, such that the array holds one more element. Next, it is supposed to copy the name of the file into the new space created. It doesn't seem to like that part, though.

bool loadTexture(char* file_name, GLuint* &texture_list, int &num_textures, string* &texture_names)
{
	texture_list = (GLuint*)realloc(texture_list, sizeof(GLuint) * (num_textures + 1));
	texture_names = (string*)realloc(texture_names, sizeof(string) * (num_textures + 1));
	texture_names[num_textures] = "hello";

This is, of course, only part of the function, it does alot more (including incrementing num_textures). It crashes on "hello" assignment line, though, saying: Unhandled exception at 0x1023b425 (msvcr70d.dll) in SpaceSim.exe: 0xC0000005: Access violation reading location 0xbaadf001. Ironic that the address of the location comes out to say "baad". Anyway, this happens on the first call to the loadTexture function, where num_textures is initially zero and texture_names is NULL (thus realloc should act just like malloc, or so says MSDN). I can't seem to figure out what's wrong. The realloc code seems ok. Can anyone give me some ideas on how to flush out the problem? Or perhaps Drew_Benton or EvilSteve would like to say something like "Well it's quite simple. Your problem is...". In fact, I think I'd like that better, though I encourage everyone to beat drew or steve to the punch. boolean, perhaps? One of the mods? Or even an AP who's just surfing the site for the first time and sees the simple error in my code (in that case welcome to GameDev!). All suppliers of miraculous solutions are welcome! Thanks in advance, guys!
Without order nothing can exist - without chaos nothing can evolve.
Advertisement
If your using C then ignore this post.

I think the problem is your using string and realloc together. realloc will copy the memory to another place if theres not enough room at the current address. This may make any pointers inside a C++ object invalid. Also the constructor of string isn't being called and I think this is the problem your having. Use std::vector, char*, or placement new.
I don't know how your string object should behave, but from what I see, you're increasing the size of an array of pointers... but you seem to fail to allocate memory for the string itself. Now I guess, depending on the compiler your "hello" string should be stored somewhere global as a const char* and reused where necessary...

What would be helpful is to know what your string object is?

If its a char* hidden in a typedef, why don't you strcpy to it?

Anyway, I hope someone will be able to help you, or post more code, I might be able to help out

Good luck

Eric
Quote:Original post by mike25025
realloc will copy the memory to another place if theres not enough room at the current address. This may make any pointers inside a C++ object invalid. Also the constructor of string isn't being called and I think this is the problem your having.


Indeed, in C++ only POD-types can be used with C memory rountines directly, if you still wanted to do it that then you'll need placement new operator how-ever you must explicitly invoke destructor (for user-defined types like std::string) before deallocating memory:

#include <new> // placement newusing std::string;//.....new(texture_names + num_textures) string("hello"); // placement new, constructs only//.....texture_names[num_textures].~string(); // explicit destruction, you must!//.....


You'll be off better using std::vector as its guaranteed to store elements contiguously and takes care of all the low-level stuff like the above. You can allocate a chunk unitialized memory (using reserve) and incrementally initialize elements later on (using say push_back). You can even use a different allocator type with the standard library containers (even for std::string which is just a type alias for std::basic_string).
Quote:Original post by xEricx
I don't know how your string object should behave, but from what I see, you're increasing the size of an array of pointers... but you seem to fail to allocate memory for the string itself.


He doesn't have an array of pointers, he has a C-style dynamic array of std::strings, but only allocates a chunk of unitialized memory using realloc, each elements needs to be constructed which you can do this via in-place construction using placement new operator.
Thanks guys. That clears up why things are blowing up on me. I shall take the appropriate measures.

And just out of curioisity, what does POD stand for?
Without order nothing can exist - without chaos nothing can evolve.
POD means Plain Old Data.

Thanks snk for clearing that up... I never use #using for clarity, so for some reason string didn't trigger in my brain that it was a std::string... I guess I'm tired =)

This topic is closed to new replies.

Advertisement