Home > Software design >  malloc(): corrupted top size when adding an element to a dynamic list
malloc(): corrupted top size when adding an element to a dynamic list

Time:11-04

I am writing a dynamic list.
Here is the header file that contains the dynamic list and the function that add an element to the list.

#if !defined(STRING_LIST)
#define STRING_LIST

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

typedef struct string_list      
{
    char **list;
    int size;

    void (*add)(struct string_list *list, char *string);
} string_list;

void add(string_list *list, char *string)
{
    int old_size = list->size;
    list->size  = 1;
    char **new_list = malloc(list->size);

    if(!new_list)
    {
        puts("Error in malloc()");
    }

    for(int i = 0; i < old_size; i  )    // assigning the elements from the old array to the new array
        new_list[i] = list->list[i];

    if (list->list != NULL)
        free(list->list);
    
    list->list = new_list;
    list->list[list->size - 1] = strdup(string);
}

string_list *string_list_construct()
{
    string_list *list = malloc(sizeof(string_list));
    list->size = 0;
    list->list = NULL;

    list->add = add;
}

void string_list_deconstruct(string_list *list)
{
    for(int i = 0; i < list->size; i  )
    {
        printf("i:%i\n", i);
        free(list->list[i]);
    }

    free(list->list);
    free(list);
}
#endif

And here is the main function

#include <stdio.h>
#include "string_list.h"

int main()
{
    string_list *list = string_list_construct();

    for(int i = 0; i < 5; i  )
    {
        list->add(list, "item");
        printf("new size: %i\n\n", list->size);
    }
    string_list_deconstruct(list);
    return 0;
}

The dynamic list is a struct that has two data fields and one function pointer which points to add function below.

And when running the code I get

new size: 1

new size: 2

new size: 3

new size: 4

malloc(): corrupted top size
Aborted

I used valgrind to chick for memory leak but I found nothing.

Any help?

CodePudding user response:

you need to differentiate between the size and the length of an array and you can use realloc() if you want to expand an array.

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

char *strdup(const char *src) {
    char *dst = malloc(strlen (src)   1);  
    if (dst == NULL) return NULL;          
    
    return strcpy(dst, src);                      
                                
}


typedef struct string_list      
{
    char **list;
    unsigned int length;
    size_t size;

    void (*add)(struct string_list *list, char *string);
} string_list;

void add(string_list *stringlist, char *string)
{
  int old_size = stringlist->size;
  stringlist->length  = 1;
  stringlist->size  = sizeof(char*);
  
  stringlist->list = realloc( stringlist->list, sizeof( char* ) * stringlist->length );
  if(!stringlist->list)
  {
    puts("Error in realloc()");
    exit(1);
  }
  

  stringlist->list[stringlist->length-1 ] = strdup(string);
}

string_list *string_list_construct()
{
    string_list *list = malloc(sizeof(string_list));
    list->size = 0;
    list->list = NULL;

    list->add = add;

    return list;
}

void string_list_deconstruct(string_list *list)
{
    for(int i = 0; i < list->length; i  )
    {
        printf("free() i-th entry:%d\n", i);
        free(list->list[i]);
    }

    free(list->list);
    free(list);
}


int main()
{
    string_list *list = string_list_construct();

    for(int i = 0; i < 5; i  )
    {
        list->add(list, "item");
        printf("new length: %d\n", list->length);
        printf("new size: %ld\n\n", list->size );
    }
    string_list_deconstruct(list);
    return 0;
}
  • Related