简体   繁体   中英

Allocation of c-struct including multiple dynamic arrays

Good Morning,

I want to store samples in a Buffer . To facilitate future modifications as well as memory-management, I would like to use a struct. Example:

#define MAX_SAMPLES  999
#define NUM_VAR3       7
#define NUM_VAR4      18

struct SampleType
{
 type1 var1;
 type2 var2;
 type3 var3[NUM_VAR3];
 type4 var4[NUM_VAR4];
};

SampleType Buffer[MAX_SAMPLES];

.

void Function_Is_Called_Each_10ms (SampleType mySample)
{
  Buffer[i] = mySample;
 ... 
}

So far so good. However, my Problem is that I also want to change the size of the arrays. I would like to initialise MAX_SAMPLES , NUM_VAR3 , and NUM_VAR4 at the beginning of my program and not have them hardcoded. Thus after initialisation would still be a static problem which is easy to handle. I imagine to add a header containing the three variables and thereby being able to store and load the buffer into/from a file.

Is there a way to do it, maybe something like the "struct-hack" (cf. How to include a dynamic array INSIDE a struct in C? )? If yes, how to do it with more than one dynamic array inside the struct?

Thanks in advance!

Best Regards, Florian


Update / Solution:

Thanks, the vector does the trick. The Buffer now has to be std::vector. To stick to the example above:

struct StaticSampleType {
type1 var1;
type2 var2;
};
StaticSampleType StaticSample;
std::vector<type3> var3;
std::vector<type4> var4;

std::vector<char> Buffer;

.

void Function_Is_Called_Each_10ms (...)
{
 static unsigned int BufferPos = Buffer_StartAddr; // exemplary

 /* Try to keep it easy editable: */
 uint StartAdress[] = {(uint)&StaticSample, (uint)&var3[0], (uint)&var4[0]};
 uint SizeToAdd[]   = {sizeof(StaticSampleType), var3.size()*sizeof(type3), var4.size()*sizeof(type4)};
 uint arrayelements  = sizeof(StartAdress)/sizeof(StartAdress[0]);

 /* Fill Buffer */
 for (unsigned int i = 0; i < arrayelements; i++)
 {
   if ( SizeToAdd[i] > 0 )
   {
   std::memcpy((void*)StartAdress[i], (void*)BufferPos, SizeToAdd[i]);
   BufferPos += SizeToAdd[i];
   }
  }     
}

There now has to be a function which initialises the Buffer. It is:

void Function_Initialise_Buffer()
{
uint buffer_size = sizeof(StaticSampleType);
buffer_size += sizeof(type3)    * var3.size();
buffer_size += sizeof(type4)    * var4.size();

/* Preallocate Buffer */
for (uint i = 0; i < 2; i++)
{
  Buffer.clear();
  Buffer.resize(buffer_size * MAX_SAMPLES); // Allocate Size
  /* Remarques: */
  Buffer_StartAddr = (uint)&Buffer[0];
  Buffer_Size   = Buffer.size();    // using char ==> Buffer.size() equals buffer_size*MAX_SAMPLES
  Buffer_EndAddr = Buffer_StartAddr + Buffer_Size;  
  }
}

Just exemplary, but I thought maybe the concept could be interesting to some people. I shortened unsigned int to uint to reduce text.

Best Regards, Florian

You can't do this. You should use std::vector . If NUM_VAR3 et al. are to be compile time constants, you can make them constexpr (you shouldn't be using macros in C++) and use std::array , but the size determination cannot take place at runtime.

What Robert said: use dynamic memory (std::vector)

In your case it will suffice to allocate all dynamic memory at the time you initialise the input sizes of your problem. Copying blocks of memory is actually cheap, so pure assignments (no re-allocating the buffers) should be fast enough.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM