Home > front end >  Why do i get a problem with freeing arrays?
Why do i get a problem with freeing arrays?

Time:09-11

so currently we are learning C and we are begining to use pointers . This program should create a array of a size given then append the a value ( here 5 ) and print the array , then delete all the content and reprint the array . Everything works fine until the free(tab.data).

Here is the struct used .

typedef struct table_t {
  double* data;
  int size
} table_t;

and the code

#include <stdlib.h>
 #include "TD1.h"

table_t table_new(int n) {
  table_t t;
  t.data = malloc(sizeof(double)*n);
}

void table_printf(table_t tab) {
  int i ;
  for(i=0;i<tab.size;i  ){
    printf("%lf \n",tab.data[i]);
  }

}

int table_append(double val, table_t tab){
  int i ;
  for(i=0;i<tab.size;i  ){
    tab.data[i]= val ;
  }
}

table_t table_delete(table_t tab)
{
    free(tab.data)  ; //Where the problem is using valgrind
 }


int main()
{
  table_t t ;
  printf(" Enter the size of the array  ");
  scanf("%d ", &t.size  );
  table_new(t.size );
  table_append(5,t);
  table_printf(t);
  table_delete(t);
  table_printf(t);


  return(0);
}

CodePudding user response:

You have a few problems with your code:

  • table_new() causes a memory leak because t is a local variable and the memory associated with it is freed after the function returns, as a result the memory you allocated and made t.data point to is leaked.

  • table_new() does not return anything but has return type table_t.

  • table_append() appends a local copy of tab not what you pass in. You passed t to this function by value in main(). This means a local copy of what you passed is made inside table_append(). So you aren't changing what was passed instead you are changing a copy which will cease to exist once the function ends.

  • table_append() returns nothing but has return type int.

  • table_delete() uses free() incorrectly. You passed this function a local variable t in main(). The variable you passed is not a pointer. In order to use it with free() it must be a pointer returned from either malloc(), calloc() or realloc().

  • table_delete() returns nothing but has return type table_t.

Here is a better version:

typedef struct table_t { 
        double *data;
        int size;
} table_t;

table_t *table_new(int n)
{   
        table_t *t = malloc(sizeof(table_t));
         
        if (t == NULL) 
            return NULL;

        t->size = n;
        t->data = malloc(sizeof(double) * n);

        if (t->data == NULL) {   
            free(t);
            return NULL;
        }
                
        return t; 
}

void table_printf(table_t *tab)
{    
     for (int i = 0; i < tab->size; i  ) {
          printf("%lf \n", tab->data[i]);
     }
}

void table_append(double val, table_t *tab)
{
    for (int i = 0; i < tab->size; i  ) {
         tab->data[i] = val;
    }
}

void table_delete(table_t *tab)
{
    free(tab->data);
    free(tab);
}


int main()
{
    int table_size;

    printf("Enter the size of the array: ");
    scanf("%d", &table_size);
     
    table_t *t = table_new(table_size);

    if (t == NULL)
        return -1;

    table_append(5, t);
    table_printf(t);
    table_delete(t);

    return 0;
}
  • Related