Saturday, July 7, 2012

Constructing variable length structs in C

A trick to using structs that have a variable sized member is to use an overloaded operator new to allocate space for the struct.

struct string
 {
   int cb; // a data member
   char sz[]; // the string data 
  void* operator new(int cb, int cbExtra)
    {
        return new char[cb+cbExtra]; 
    }
 };
Now contrast the following code to create such a struct:
   
  ...
 string* pStr = new(strlen(pszInString)) string; 
 ...

The "C" method of working with variable sized looks like this 

...
 string* = (string*)new char[sizeof(string) + strlen(pszInString)];
... 

More Good Example:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>


#define MAX_QA_SIZE 256


struct tagQandA
{
   char *question;
   char answer[MAX_QA_SIZE];
};


int main(void)
{
   struct tagQandA test[5];


   int i = 0;
   for (; i < sizeof(test) / sizeof(test[0]); ++i)
   {
      // Question is a pointer, so there's no memory allocated to contain data,
      // so we do so here, i.e., it's dynamically allocated
      test[i].question = malloc(MAX_QA_SIZE);
      strcpy(test[i].question, "This is a question");


      // No need to allocate memory here, it's built into the struct definition
      // i.e., it's statically allocated
      strcpy(test[i].answer, "This is an answer");
   }


   for (i = 0; i < sizeof(test) / sizeof(test[0]); ++i)
   {
      printf("Q%d: %s\nA: %s\n", i + 1, test[i].question, test[i].answer);
      // Must free any dynamically-allocated memory, so free the question's memory
      free(test[i].question);
      // No need to free answer's memory, as it was not dynamically allocated
   }
   return 0;
}

1 comment:

  1. r1rk9np7bpcsfoeekl0khkd2juj27q3o-a-fc-opensocial.googleusercontent.com

    ReplyDelete