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.

Recommended Answers

All 11 Replies

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 ) );

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.

Ali

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.

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

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;
}

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.

> 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.

commented: Let's make these thanks from new people count. ;-) +6

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...

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;
}

> 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.

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?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.