Sign in to follow this  
Mari_p

Declaring dynamic arrays inside structures

Recommended Posts

Please, what is the correct way to declare a dynamic array inside a structure (in true, inside an array of structures)? I was thinking in something like this:
struct MY_STRUCT
{
   ...
   DWORD *array;
   ...
};

MY_STRUCT *var = new MY_STRUCT[N];
var->array = new DWORD[M];
Thanks in advance

Share this post


Link to post
Share on other sites
Quote:
Original post by Mari_p
[code]
struct MY_STRUCT
{
...
DWORD *array;
...
};

MY_STRUCT *var = new MY_STRUCT[N];
var->array = new DWORD[M];
That's correct (except that there seems to be some confusion as to whether or not var is supposed to be an array).

However, unless you're restricted to C for some reason, you'd be better off using std::vector.

Share this post


Link to post
Share on other sites
Quote:
Original post by Mari_p
Please, what is the correct way to declare a dynamic array inside a structure (in true, inside an array of structures)?
I was thinking in something like this:


struct MY_STRUCT
{
...
DWORD *array;
...
};

MY_STRUCT *var = new MY_STRUCT[N];
var->array = new DWORD[M];


Thanks in advance


#include <vector>

struct MY_STRUCT {
...
std::vector< DWORD > array;
...
};

std::vector< MY_STRUCT > var( N );
var[0].array.resize( M );


Unlike your posted example, this will not leak :).

@jyk: new isn't legal C :).

Share this post


Link to post
Share on other sites
Quote:
Original post by MaulingMonkey
@jyk: new isn't legal C :).
Hehe, well I do know that :-) But obviously somewhere between reading the original post and writing my reply I forgot that the OP had used new [Edit: as well as C++-style struct syntax].

How embarrassing :-|

Share this post


Link to post
Share on other sites
Quote:
Original post by jyk
Quote:
Original post by MaulingMonkey
@jyk: new isn't legal C :).
Hehe, well I do know that :-) But obviously somewhere between reading the original post and writing my reply I forgot that the OP had used new. How embarrassing :-|


Hardly embarrassing, the code originally posted stinks badly of C. Non-RAIIed pointers, non-containered arrays, getting within 3 miles of the Win32 API (DWORD), etc. - I just hawk around for the most subtle indicators that allow me to assert that since C++ is being used, you should/must/will use the standard library instead of pretending it's C :P.

(EDIT to reply to EDIT: "struct ____ { ... };" is legal C, you'll just need to use "struct _____" every time you want to use it. Typedefs just eliminate the extranious keyword, although I guess this is another point against the legality of the MY_STRUCT *var = ...; line as C code :P)

Share this post


Link to post
Share on other sites
Quote:
Original post by MaulingMonkey
(EDIT to reply to EDIT: "struct ____ { ... };" is legal C, you'll just need to use "struct _____" every time you want to use it. Typedefs just eliminate the extranious keyword, although I guess this is another point against the legality of the MY_STRUCT *var = ...; line as C code :P)
Yes, my 'edit' comment was simply in reference to the fact that in the given context, 'MY_STRUCT *var = ...;' is not legal C.

Share this post


Link to post
Share on other sites
Thank you much, guys.

I implemented dynamic arrays using the two ways (new and vector)... but I am getting an annoying CXX0030 error. :(

The relevant code is:

struct M_FILE_DATA_EX
{
DWORD tempo;
std::vector<BYTE> roboID;
std::vector<FLOAT> x;
std::vector<FLOAT> y;
std::vector<FLOAT> theta;
std::vector<BOOL> carregado;
};

std::vector<M_FILE_DATA_EX> ArrayDadosEx;

DWORD nroLinhas = 10869;
BYTE nroRobos = 5;

VOID AlimentaArrayDadosEx()
{
ArrayDadosEx.resize(nroLinhas);

ArrayDadosEx[0].carregado.resize(nroRobos);
ArrayDadosEx[0].roboID.resize(nroRobos);
ArrayDadosEx[0].x.resize(nroRobos);
ArrayDadosEx[0].y.resize(nroRobos);
ArrayDadosEx[0].theta.resize(nroRobos);

...

for ( DWORD i = 0 ; i < nroLinhas ; i++ )
{

...

for ( BYTE rob = 0 ; rob < nroRobos ; rob++ )
{
if ( i > 0 )
{
ArrayDadosEx[i].roboID[rob] = (ArrayDadosEx[i-1].roboID[rob]);
ArrayDadosEx[i].x[rob] = ArrayDadosEx[i-1].x[rob];
ArrayDadosEx[i].y[rob] = ArrayDadosEx[i-1].y[rob];
ArrayDadosEx[i].theta[rob] = ArrayDadosEx[i-1].theta[rob];
ArrayDadosEx[i].carregado[rob] = ArrayDadosEx[i-1].carregado[rob];
}
}

...

}

...

}




I got the error when i = 4279. Please, would anybody have some idea on how to solve that?

Thanks again.

Share this post


Link to post
Share on other sites
please use .at(int) instead of the [] operators for std::vectors. if you exceed the vector's limits, at() will throw at least an exception, so you know what the problem is.

Share this post


Link to post
Share on other sites
After a lot of attempts I decided to restart my machine and the code simply worked. But I'm now getting another error when I close the application. The error is:

DAMAGE: after Normal Block (#389) at 0x00B63A60

When I debug it, I notice the error is exclusively related to std::vector. Any ideas?

Share this post


Link to post
Share on other sites
You are only resizing the vector members of ArrayDadosEx[0]. You are then attempting to access 0-5 of the vector members all the other elements of ArrayDadosEx.

You need to move your resize code into the loop and resize ArrayDadosEx[i].members for all of i.


VOID AlimentaArrayDadosEx()
{
ArrayDadosEx.resize(nroLinhas);

...

for ( DWORD i = 0 ; i < nroLinhas ; i++ )
{

ArrayDadosEx[i].carregado.resize(nroRobos);
ArrayDadosEx[i].roboID.resize(nroRobos);
ArrayDadosEx[i].x.resize(nroRobos);
ArrayDadosEx[i].y.resize(nroRobos);
ArrayDadosEx[i].theta.resize(nroRobos);

...

for ( BYTE rob = 0 ; rob < nroRobos ; rob++ )
{
if ( i > 0 )
{
ArrayDadosEx[i].roboID[rob] = (ArrayDadosEx[i-1].roboID[rob]);
ArrayDadosEx[i].x[rob] = ArrayDadosEx[i-1].x[rob];
ArrayDadosEx[i].y[rob] = ArrayDadosEx[i-1].y[rob];
ArrayDadosEx[i].theta[rob] = ArrayDadosEx[i-1].theta[rob];
ArrayDadosEx[i].carregado[rob] = ArrayDadosEx[i-1].carregado[rob];
}
}

...

}






I'm not sure what your assignments in the inner loop are trying to do. I assume you are assigning values to ArrayDadosEx[0]'s members somewhere in your ...'s. Given that your inner loop then seems to propegate these values up through the entire array, I'd suspect it would be clearer to just assign to the whole array in a loop when you assign to [0], although I don't know what else is going in in the ...'s, so I may be off track.

You can also just assign one vector to another if they are the same type, so:


for ( BYTE rob = 0 ; rob < nroRobos ; rob++ )
{
...
ArrayDadosEx[i].roboID[rob] = (ArrayDadosEx[i-1].roboID[rob]);
...
}


can be expressed more easily as:


ArrayDadosEx[i].roboID=ArrayDadosEx[i-1].roboID;


But equally, since all the members of M_FILE_DATA_EX can be handled by default copying, you could just do:


ArrayDadosEx[i]=ArrayDadosEx[i-1];


as far as I can see.

Or just set up the M_FILE_DATA_EX once, and do:


M_FILE_DATA_EX Ex;

// set up Ex

ArrayDadosEx.resize(nroLinhas,Ex);


unless I'm confused about what your code is trying to do. Apologies if so.

Share this post


Link to post
Share on other sites
Thank you very much, EasilyConfused.

Resizing ArrayDadosEx[i].members into the loop eliminated the error. [smile]

Quote:

I'm not sure what your assignments in the inner loop are trying to do. I assume you are assigning values to ArrayDadosEx[0]'s members somewhere in your ...'s. Given that your inner loop then seems to propegate these values up through the entire array, I'd suspect it would be clearer to just assign to the whole array in a loop when you assign to [0], although I don't know what else is going in in the ...'s, so I may be off track.

I really need to do ArrayDadosEx[i].roboID[rob] = ArrayDadosEx[i-1].roboID[rob] in the inner loop. To understand better, please take look at my complete function:


VOID AlimentaArrayDadosEx()
{

ArrayDadosEx.resize(nroLinhas);

BYTE roboID_linha;
FLOAT x_linha;
FLOAT y_linha;
FLOAT theta_linha;
BOOL carreg_linha;


// Alimentando o array de dados
for ( DWORD i = 0 ; i < nroLinhas ; i++ )
{
ArrayDadosEx[i].carregado.resize(nroRobos);
ArrayDadosEx[i].roboID.resize(nroRobos);
ArrayDadosEx[i].x.resize(nroRobos);
ArrayDadosEx[i].y.resize(nroRobos);
ArrayDadosEx[i].theta.resize(nroRobos);

// tempo do sistema
for (int j = 0 ; j < 7 ; j++ )
fscanf(mFile, "%d", &ArrayDadosEx[i].tempo);

// agv
fscanf(mFile, "%d", &roboID_linha);

// state (pula)
fscanf(mFile, "%s", stringTemp);

// x,y, theta
fscanf(mFile, "%f", &x_linha);
fscanf(mFile, "%f", &y_linha);
fscanf(mFile, "%f", &theta_linha);

// node (pula)
fscanf(mFile, "%s", stringTemp);

// loaded
fscanf(mFile, "%d", &carreg_linha);


// Alimentando o array
for ( BYTE rob = 0 ; rob < nroRobos ; rob++ )
{
if ( roboID_linha == rob + 1 )
{
ArrayDadosEx[i].roboID[rob] = roboID_linha;
ArrayDadosEx[i].x[rob] = x_linha;
ArrayDadosEx[i].y[rob] = y_linha;
ArrayDadosEx[i].theta[rob] = theta_linha;
ArrayDadosEx[i].carregado[rob] = carreg_linha;
}
else
{
if ( i > 0 )
{
ArrayDadosEx[i].roboID[rob] = ArrayDadosEx[i-1].roboID[rob];
ArrayDadosEx[i].x[rob] = ArrayDadosEx[i-1].x[rob];
ArrayDadosEx[i].y[rob] = ArrayDadosEx[i-1].y[rob];
ArrayDadosEx[i].theta[rob] = ArrayDadosEx[i-1].theta[rob];
ArrayDadosEx[i].carregado[rob] = ArrayDadosEx[i-1].carregado[rob];
}
}
}

// Indo para a próxima linha
while ( fgetc(mFile) != '\n' )
{
}
}

fclose(mFile);

}




Basically, I'm extracting data from a MatLab file and storing the values in the ArrayDadosEx. The file contains positions (x,y,theta) of 5 robots. There are 10869 lines, so that each line stores the system time, the position of a robot and the ID of this robot. There is no orderly sequence of the robots' ID along the file.

I created the ArrayDadosEx because my application needs to know the positions of all robots at each line of the file, that is, if a line is referred to robot whose ID = 3, at this same time, I need to know the positions of the other robots.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this