• Advertisement

Archived

This topic is now archived and is closed to further replies.

How to dynamically allocate an array of structures?

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

Hi I'm wondering how you can dynamically allocate RAM for an array of structures in C++. I've made a program which reads in a file and stores the Colour Map data in a bit-field structure which is kept in a the header file. Here is what I have done so far:

struct ColourRegister
{
	unsigned char red : 8;		// 0 (Black) to 255 (White)

	unsigned char green : 8;
	unsigned char blue : 8;
					// JUST A TEST STRUCTURE

} ColourMap[256];



// Later in the C++ program I read the data into the bit-field array...

if(fread(&ColourMap, 1, chunkLength, fp) != chunkLength)
{
	cout << "ERROR: Unable to read the ILBM file's Color Map!" << endl;
	return FALSE;
}
As you can see I've created an array of the structure and called it ColourMap which can hold 256 values (colours). Then I read the ColourMap data into the array with no problems. What I want to do though is dynamically allocate the RAM for the ColourMap array because the palette does not always contain 256 colours. Sometimes it has just 16 colours or 32 colours and I want the array to match this. Any idea how I go about doing this? I'll post a bit more info in a minute... [edited by - Steve-B on April 15, 2004 10:47:14 AM]

Share this post


Link to post
Share on other sites
Advertisement
Here is the sort of code I want to produce. This worked with no errors when I tested it however it only allocated enough RAM to hold one structure. I would like the array to be held in a pointer to the structure a bit like this:


// This is stored in the program header file...

struct ColourRegister
{
unsigned char red : 8; // 0 (Black) to 255 (White)

unsigned char green : 8;
unsigned char blue : 8;
// THIS STRUCTURE WORKS

};


// Later in the C++ program is this code...

ColourRegister *colourMap[16];



if((colourMap = new ColourRegister [map_size]) == NULL)
{
cout << "Error: Couldn't allocate memory for the ColourMap data!" << endl;
fclose(fp);
return FALSE; // WORKS TO A DEGREE (ALLOCATES RAM THO NOT FOR AN ARRAY)

}


[edited by - Steve-B on April 15, 2004 10:53:45 AM]

Share this post


Link to post
Share on other sites
Hmmm. Thanks for the link but it doesn''t really help me much. I already know how to dynamically allocate an array in C++. The problem I''m having is trying to dynamically allocate an array of structures.

Share this post


Link to post
Share on other sites
quote:
Original post by Steve-B
I already know how to dynamically allocate an array in C++. The problem I''m having is trying to dynamically allocate an array of structures.


An array is an array. If you can allocate arrays of basic data types, you can allocate arrays of more complex data types (like structures) exactly the same way:


ColourRegister *colourMap = new ColourRegister [numColours];

Share this post


Link to post
Share on other sites
Hi BriTeg

Thanks for the response. Looks like we''re thinking along the same lines because that is the exact same code that I tried out on my program (see the source box above) however it didn''t work. I guessed I had done something wrong in my program but you seem to confirm that what I''m doing is right. I wonder why it still doesn''t work then.

I''ll tell you the problem. When I tried the code earlier (before you suggested it) I thought it would create the array of structures I was looking for. Instead (as you can see from the comment I added) all it seems to do is allocate some RAM for just the Red Green and Blue. I found this by using the debugger on VC++ 6. It didn''t create an array like I thought it would. So I started thinking maybe the structure needed to be defined differently (maybe with empty [] brackets) but nothing worked.

When I use the debugger and use the first method to hard code my array of 256 structures it shows up with all 256 arrays (with little + boxes next to each element in the array). Nothing like this is created when I try do dynamically allocate the array of structures. I''m really at a loss with this. Just what the hell am I doing wrong.

Share this post


Link to post
Share on other sites
I don''t think you''re doing anything wrong, but rather the debug windows are sometimes non-intuitive. Using this method, because colourMap is initially declared as simply a pointer (a pointer that is later set to point to an allocated array), the debugger treats is as simply a pointer in the debugging windows (ie. the debugger doesn''t treat it as an array). It is still allocating the memory, and to see it, in your watch window you have to explicitly watch "colourMap[0]", "colourMap[1]", "colourMap[100]", "colourMap[255]", etc.

Share this post


Link to post
Share on other sites
There is one posibility.
If you have pointers in the structure you may have to allocate extra memory.
Although im not sure this is necessary in c++''s ''new'' command.
Say there is a boolean pointer in it:

whatever = new Struct[size*sizeof(bool)];

Share this post


Link to post
Share on other sites
Here''s the code you currently have:
ColourRegister *colourMap[16];
if((colourMap = new ColourRegister [map_size]) == NULL)


What you''re doing is declaring a static array of 16 ColourRegister pointers. The second line shouldn''t even compile correctly - you''re converting from ColourRegister* to ColourRegister*[16]. What you want to do is get rid of the [16] part -
ColourRegister *colourMap;
if((colourMap = new ColourRegister[map_zie]) == NULL)


CProgrammer - that''s not right, you don''t need an extra "* sizeof(whatever)" when using the new operator. It''s understandable that you would think that since you''re obviously a C programmer who uses malloc(). The number in the brackets says the number of objects you want to allocate, not the number of bytes.

Share this post


Link to post
Share on other sites
If you don''t really need to use an array you could also use a vector which is part of the c++ template libraries.
Vector are really powerful because they are dynamic and if you ask me much more powerful than arrays. Many functions are also provided which makes they really easy to use too.

Example:

#include <vector>

using namespace::std;

// Declare a vector array with pointers to a struct

vector name;

Thats all.

When adding to the array simply use the push_back function.

YOUR_STRUCT myStruct;

name.push_back(&myStruct);

Check out this page for an exellent tutorial:
http://www.codeguru.com/Cpp/Cpp/cpp_mfc/arrays/article.php/c4071/

Share this post


Link to post
Share on other sites
The decaration part seems to have messed up a little...

Anywayz to declare a vector do this...

vector < YOUR_STRUCT* > name;

Share this post


Link to post
Share on other sites
quote:
Original post by CProgrammer
There is one posibility.
If you have pointers in the structure you may have to allocate extra memory.
Although im not sure this is necessary in c++''s ''new'' command.
Say there is a boolean pointer in it:

whatever = new Struct[size*sizeof(bool)];


... What on Earth are you talking about?

Operator new as used in, say, ptr = new type_t[n] allocates n*sizeof(type_t) bytes of memory, which is exactly what you need. If you are referring to situations where the class itself has dynamically allocated members, then it is the duty of the class constructor to allocate this (and operator new calls the constructor, so this is not a problem).

Share this post


Link to post
Share on other sites
quote:
Original post by BriTeg
I don't think you're doing anything wrong, but rather the debug windows are sometimes non-intuitive. Using this method, because colourMap is initially declared as simply a pointer (a pointer that is later set to point to an allocated array), the debugger treats is as simply a pointer in the debugging windows (ie. the debugger doesn't treat it as an array). It is still allocating the memory, and to see it, in your watch window you have to explicitly watch "colourMap[0]", "colourMap[1]", "colourMap[100]", "colourMap[255]", etc.

Hi peeps.

Ah some interesting comments since I've been gone. lol. Just thought I'd let you guys know (cos I know you won't get to sleep unless I tell you this) that I've finally managed to get it to work properly. Woohoo. lol.
BriTeg, you're right about VC++ debug info. When I typed in colourMap[0] instead of just "colourMap" into the watch boxes then the data appeared correctly.

But that was just 50% of the problem. The other 50%? Well take a look at the code I posted first. Notice I'm using fread to read in the 32-bit chunkLength. Now the program has changed and I'm reading the data into RAM through a pointer variable. I forgot to remove the address operator. It's not usually a good idea to use the address operator with pointers! LOL.

I've tested it completely and it's working exactly as I hoped now.

quote:
What you're doing is declaring a static array of 16 ColourRegister pointers. The second line shouldn't even compile correctly - you're converting from ColourRegister* to ColourRegister*[16]. What you want to do is get rid of the [16] part.

Yes you're right. That bit of code wouldn't compile correctly but that is from two different versions that I was testing. I posted the wrong bit of code there. Doh. lol.

Thanks a lot for your help!

Steve B

[edited by - Steve-B on April 24, 2004 6:45:29 AM]

[edited by - Steve-B on April 24, 2004 6:51:19 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by Pipo DeClown
a_class* a_ptr = new a_class(something) [16]; // Compile error

How is this done?

I don''t believe standard C++ allows what you''re evidently trying to do (i.e. allocate an array of a_class objects passing ''something'' to the constructor?); you could create a dynamic array of pointers (i.e. a pointer to a pointer) and allocate each individual object in the usual fashion ... Better yet, you could just use std::vector<a_class>.

Share this post


Link to post
Share on other sites

  • Advertisement