954,505 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Struct with variable length arrays of struct

I need to create a data structure of data structures, but I can know "how many structs I need" only at runtime.

typedef struct tagPredefinedStruct{
   int   iSize;
   int   iCount;
} PREDEFINEDSTRUCT;

int x;
x = GetNumberofStructs();  //x is known only at runtime.

typedef struct APIStruct {
   int                iNumber;
   PREDEFINEDSTRUCT   PreDefStruct[x];
   int                iDate;
} APISTRUCT;


Currently, the compiler gives an error C2057: expected constant expression for PreDefStruct[x] .

I have to pass the address of this APISTRUCT structure to an API so I need all the memory allocated together in a chunk and can't use linked lists.

Thanks a lot for reading my post. I graciously await your response.

mohammadalipak
Newbie Poster
19 posts since Jul 2007
Reputation Points: 10
Solved Threads: 0
 

You can't set the size of an array at run time. You have to dynamically create the array from a pointer.

typedef struct tagPredefinedStruct{
   int   iSize;
   int   iCount;
} PREDEFINEDSTRUCT;

typedef struct APIStruct {
   int                iNumber;
   PREDEFINEDSTRUCT   *PreDefStruct;
   int                iDate;
} APISTRUCT;

APISTRUCT api;
int x;

x = GetNumberofStructs();  //x is known only at runtime.
api.PreDefStruct = malloc( x * sizeof( PREDEFINEDSTRUCT ) );
Hamrick
Posting Whiz
325 posts since Jun 2007
Reputation Points: 180
Solved Threads: 34
 

Thanks for the help. It compiles fine now. However, it crashes when I try to assign a value to the data structure.

.
.
.
x = GetNumberofStructs();  //x = 3 in this case
api.PreDefStruct = malloc( x * sizeof( PREDEFINEDSTRUCT ) );
api.PreDefStruct[0].iSize = 4; //here it crashes


Please help. Thanks.My friend said another way is to give it an initial size of the array then change that size later. I don't know how to implement it though.

[TEX]Ali[/TEX]

mohammadalipak
Newbie Poster
19 posts since Jul 2007
Reputation Points: 10
Solved Threads: 0
 
However, it crashes when I try to assign a value to the data structure.


Check the pointer to see if it's 0. If it is then malloc failed to allocate the memory.My friend said another way is to give it an initial size of the array then change that size later.
You can't. Array sizes have to be constant and they can't be changed. A variable sized array is what I showed you.

Hamrick
Posting Whiz
325 posts since Jun 2007
Reputation Points: 180
Solved Threads: 34
 

The pointer is not zero. It's assigned a memory location of 0x6e615c31 .

mohammadalipak
Newbie Poster
19 posts since Jul 2007
Reputation Points: 10
Solved Threads: 0
 

Does this work for you?

#include <stdio.h>

typedef struct tagPredefinedStruct{
  int   iSize;
  int   iCount;
} PREDEFINEDSTRUCT;

typedef struct APIStruct {
  int                iNumber;
  PREDEFINEDSTRUCT   *PreDefStruct;
  int                iDate;
} APISTRUCT;

int main( void ) {
  APISTRUCT api;

  api.PreDefStruct = malloc( 3 * sizeof( PREDEFINEDSTRUCT ) );

  api.PreDefStruct[0].iSize = 0;
  api.PreDefStruct[1].iSize = 1;
  api.PreDefStruct[2].iSize = 2;

  printf( "%d\n", api.PreDefStruct[0].iSize );
  printf( "%d\n", api.PreDefStruct[1].iSize );
  printf( "%d\n", api.PreDefStruct[2].iSize );

  free( api.PreDefStruct );

  return 0;
}
Hamrick
Posting Whiz
325 posts since Jun 2007
Reputation Points: 180
Solved Threads: 34
 

No, it's not working. It crashes on line 19 of your proposed code: api.PreDefStruct[0].iSize = 0; . Thanks for continuing to help. And so promptly.

mohammadalipak
Newbie Poster
19 posts since Jul 2007
Reputation Points: 10
Solved Threads: 0
 

> It's assigned a memory location of 0x6e615c31
Which looks a lot like a string fragment of "na\1"

The \ is telling, does it look like part of a filename perhaps?

I'm betting that you're copying a string into some other allocated memory, and this is where you observe the trashing of memory as a crash.

Salem
Posting Sage
Team Colleague
11,531 posts since Dec 2005
Reputation Points: 5,862
Solved Threads: 953
 

Thanks for all your help, but I don't think my problem can be solved using a struct in this manner.

What I need is all of the data items of the struct allocated together in one chunk. What I'm seeing from my debugger is that the 1st data item is allocated at: 0x0426c814 , the 2nd at: 0x6674725c & so on...

mohammadalipak
Newbie Poster
19 posts since Jul 2007
Reputation Points: 10
Solved Threads: 0
 

I read about a trick that makes everything together. Move the PreDefStruct member to be last, make it an array of 1, and then make the APISTRUCT variable dynamic. If you allocate the size of APISTRUCT plus the size of x PREDEFINEDSTRUCTs I think you get what you need.

#include <stdio.h>

typedef struct tagPredefinedStruct{
  int   iSize;
  int   iCount;
} PREDEFINEDSTRUCT;

typedef struct APIStruct {
  int                iNumber;
  int                iDate;
  PREDEFINEDSTRUCT   PreDefStruct[1];
} APISTRUCT;

int main( void ) {
  APISTRUCT *api = malloc( sizeof( APISTRUCT ) + 3 * sizeof( PREDEFINEDSTRUCT ) );

  api->PreDefStruct[0].iSize = 0;
  api->PreDefStruct[1].iSize = 1;
  api->PreDefStruct[2].iSize = 2;

  printf( "%d\n", api->PreDefStruct[0].iSize );
  printf( "%d\n", api->PreDefStruct[1].iSize );
  printf( "%d\n", api->PreDefStruct[2].iSize );

  free( api );

  return 0;
}
Hamrick
Posting Whiz
325 posts since Jun 2007
Reputation Points: 180
Solved Threads: 34
 

> debugger is that the 1st data item is allocated at: 0x0426c814, the 2nd at: 0x6674725c & so on...
Let me re-iterate my previous post.
Your 2nd address again looks like a printable string ("ftr\"), so you're mistaking bugs elsewhere in your code as something else.

If there is only one malloc, then all the data is contiguous.

Salem
Posting Sage
Team Colleague
11,531 posts since Dec 2005
Reputation Points: 5,862
Solved Threads: 953
 

I found another way of working it using realloc(). Salem, how can you read the string from addresses? That's soooo amazing! Can you please tell me?

mohammadalipak
Newbie Poster
19 posts since Jul 2007
Reputation Points: 10
Solved Threads: 0
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You