Question

I have a function that return me a union array, I need to free a union array after I use it.

An updated code :

This is a struct

typedef union _data {
    float F;
    uint8_t  B[4];
} floatCharFunction;

This is a Read Function:

void HW_SWversion(version state,floatCharFunction* ver)
{
  floatCharFunction fVersionRead[2] = {0,0};//SW-HW
  *ver = *fVersionRead;
  //floatCharFunction SW,HW;
  if(state == SAVE_VERSION)
  {
    FLASH_ERASE(_4KB,VERSION_BASE_ADDR);    
    fVersionRead[0].F =VERSION_SW;
    fVersionRead[01].F =VERSION_HW;
    FLASH_WRITE(fVersionRead[0].B,VERSION_BASE_ADDR,VERSION_SIZE_IN_BYTES/2);
    FLASH_WRITE(fVersionRead[1].B,VERSION_BASE_ADDR+VERSION_SIZE_IN_BYTES/2,VERSION_SIZE_IN_BYTES/2);
  }else if(state == READ_VERSION)
  {
    FLASH_READ(VERSION_BASE_ADDR,fVersionRead[0].B, VERSION_SIZE_IN_BYTES/2);
    FLASH_READ(VERSION_BASE_ADDR+VERSION_SIZE_IN_BYTES/2,fVersionRead[1].B, VERSION_SIZE_IN_BYTES/2);
    //u16VersionRead = (versions[0] << 8) | versions[1];


  }else return;
}

This is a Main :

main()
{
  floatCharFunction* ver = malloc(2*sizeof(*ver));
if (ver == NULL) {
   //printf("out of memory\n");
    exit(1);
}
HW_SWversion(READ_VERSION,ver);
free(ver);
}
Was it helpful?

Solution

There are two problems in your code:

  • ver = HW_SWversion(READ_VERSION); reassigns ver, leaking the memory you allocated in the previous line
  • HW_SWversion returns a pointer to an automatic variable that immediately goes out of scope. Consequences of accessing this variable are undefined.

The easiest change here would be to change HW_SWversion to update a pointer to a client allocated instance.

void HW_SWversion(version state, floatCharFunction* ver)
{
    /* assign version info */
}

int main()
{
    floatCharFunction ver[2];
    HW_SWversion(READ_VERSION, &ver);
}

Or, if you want to use dynamically allocated memory

void HW_SWversion(version state, floatCharFunction* ver)
{
    /* assign version info */
}

int main()
{
    floatCharFunction* ver = malloc(2*sizeof(*ver));
    if (ver == NULL) {
        printf("out of memory\n");
        exit(1);
    }
    HW_SWversion(READ_VERSION, ver);
    free(ver);
}

OTHER TIPS

As I can see, the

floatCharFunction fVersionRead[2];//SW-HW

Is a local variable and usage:

ver = HW_SWversion(READ_VERSION);

In this case is an undefined behavior because fVersionRead is allocated on stack. No one guarantees that result will be correct.

Decide, stack or heap? (but not both)

/* Stack (Note static) */
static floatCharFunction fVersionRead[2]; //SW-HW
floatCharFunction *pVersion = fVersionRead;
return pVersion;

/* Heap */
floatCharFunction *ver  = (floatCharFunction *)malloc(2*sizeof(floatCharFunction));

The keyword static extends the lifetime of a variable outside the function.

If you go for stack don't call free, else free(ver); is what you need.

i need to free an union array after i use it.

by the time you even get to using it, the array is already "freed". Since it's a local variable with automatic storage duration, it goes out of scope and is deallocated when the function returns. So, you are using a pointer to a nonexistent object, so your code currently invokes undefined behavior.

You'd be better off malloc()ing the array and returning a pointer to its first element. Then, of course, you will need to free() it (just like in your code) afterwards.

But I'm sure any introductory C book could have shown you this.

Problems with your code are::

  • You are mallocing some memory for floatCharFunction in your main.
  • You are not giving this memory to your HW_SWversion to populate or modify.
  • You are using some memory for floatCharFunction on stack in your HW_SWversion, scope:: local to HW_SWversion.
  • You are returning the memory address of an automatic variable.
  • The local variable goes out-of-scope as soon as HW_SWversion exits.
  • You are trying to free that out-of-scope memory which will cause Undefined Behaviour.
  • Your malloced memory pointer value is lost, so memory leak.

Solution::

Either do not use malloc and pass the memory as parameter to HW_SWversion like this::

void HW_SWversion(version state, floatCharFunction* ver)
{
    *ver = /* assign version info */
}

int main()
{
    floatCharFunction ver[2];
    HW_SWversion(READ_VERSION, &ver);
}

OR

If you want to use dynamic allocation::

floatCharFunction* HW_SWversion(version state)
{
  floatCharFunction *pVersion = malloc(2*sizeof(floatCharFunction));
  return pVersion;
}

main()
{
//
  floatCharFunction *ver = HW_SWversion(READ_VERSION);
  free (ver) ;
}

maybe you can try this free(ver)

the system remembers the memory location of ver, and knows the size of memory of the this ptr holds

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top