Search code examples
carraysrealloc

Failed reallocation assignment


My program is a command line database program. It's a mini. You can create an entity inside database. Command is like "CREATE ENTITY name". And I have a problem in creating entity function.

I reallocate memory for my struct array. Just I am expanding. But after second expansion, I am losing character array of second element(ankara) of expanded array. Let's look at the code;

void task_create_entity(char* name)
{
int status;
ENTITY *e = create_entity(name, &status);
if(e)
{
    if(db->entities == NULL)
    {
        db->entities = new_entity_list(4);
        db->list_size = 4;
        db->entities[0] = e;
        db->size = 1;
    }
    else
    {
        int old_list_size = db->list_size;
        if(db->size >= db->list_size)
        {
            ENTITY **temp = expand_entity_list(db->entities, &db->list_size);
            if(temp != NULL)
            {
                if(db->entities != temp)
                    db->entities = temp;
            }
            else
            {
                printf("Operating system did not allocate memory, entities list could not expanded\n");
                drop_entity(e);
                db->list_size = old_list_size;
                return;
            }
        }
        db->entities[db->size++] = e;
    }
    task_list_entities();
}
else
{
    if(status == 1)
    {
        printf("Already exists a entity in database with this name\n");
    }
    else if(status == 2)
    {
        printf("Entity file could not created\n");
    }
}
}

This function creates entity and appends array which in DB(struct). If array size is small, my function expands it and appends it. I am printing my entities name with task_list_entities() function, after I created new entity. Console inputs and outputs are:

CREATE ENTITY istanbul
istanbul

CREATE ENTITY ankara
istanbul
ankara

CREATE ENTITY seul
istanbul
ankara
seul

CREATE ENTITY monako
istanbul
ankara
seul
monako

CREATE ENTITY manchester
istanbul
ankara
seul
monako
manchester

CREATE ENTITY paris
istanbul
ankara
seul
monako
manchester
paris

CREATE ENTITY lizbon
istanbul
ºÖW
seul
monako
manchester
paris
lizbon

List starts with 4 element and expands as 4, 6, 9, 13, ... This is code of expansion:

ENTITY** expand_entity_list(ENTITY** entities, uint32_t* size)
{
    *size = *size + (*size / 2);
    return (ENTITY**) realloc(entities, *size);
}

After second expansion operation, I am losing name of second entity(ankara).

ENTITY* create_entity(char* name, int* status)
{
    ENTITY *entity = (ENTITY*) malloc(sizeof(ENTITY));
    entity->file = NULL;
    entity->name = duplicate_string(name);
    entity->records = NULL;
    entity->size = 0;
    entity->commited = 0;
    *status = 0;
    return entity;
}

This is new entity list function:

ENTITY** new_entity_list(uint32_t size)
{
    return (ENTITY**) malloc(sizeof(ENTITY*) * size);
}

and this is string duplication function:

char* duplicate_string(char* origin)
{
    char *dup = (char*) malloc(sizeof(char) * (strlen(origin) + 1));
    strcpy(dup, origin);
    return dup;
}

As a result I couldn't find the cause of the error. Other value of entity are not lost. Just char* name. This is entity struct:

typedef struct entity
{
    char *name;
    FILE *file;
    RECORD **records;
    int size;
    uint8_t commited;
} ENTITY;

Solution

  • ENTITY** expand_entity_list(ENTITY** entities, uint32_t* size)
    {
        *size = *size + (*size / 2);
        return (ENTITY**) realloc(entities, *size);
    }
    

    Is *size in bytes or in entities? You seem to assume you can store *size pointers in entities, but you only allocate *size characters. I doubt pointers are one byte on your platform!

    You probably want:

        return (ENTITY**) realloc(entities, *size * sizeof(ENTITY*));