Home > Enterprise >  Malloc for char** results in a corrupted top size
Malloc for char** results in a corrupted top size

Time:03-31

I am making a config reader for an application I am making. What I am trying to fix is that whenever I add another entry '{}' to the config, it will break the application. I have pinpointed the problem, but have no idea how to go about this.

C (config.c):

#include <config.h>

struct Config read_config(char * cfg) {
    struct Config newCfg;
    newCfg.valuesSize = 0;
    int configIsMalloc = 0;

    char * config;
    if (file_exists(cfg)==0) { 
        config = cfg;
    }
    else {
       config = read_file(cfg);
       configIsMalloc=1;
    }

    newCfg.values = (char****)malloc(sizeof(char****)*strlen(config));
    int valuesPtr = 0;
    int needsMalloc = 1;

    while(config) {
        char * nextLine = strchr(config, '\n');
        if (nextLine) *nextLine = '\0';

        printf("%s\n", config);

        if (config[0] == '{') {
            if (needsMalloc==0) {
                //newCfg.values[newCfg.valuesSize] = (char***)realloc(newCfg.values[newCfg.valuesSize], newCfg.valuesSize*(sizeof(char***)*sizeof(config)));
            }
            else {
                newCfg.values[newCfg.valuesSize] = (char***)malloc(sizeof(char***)*strlen(config));
                needsMalloc=0;
            }
        }
        else if (strstr(config, "}")) {
            newCfg.valuesSize  ;
            valuesPtr=0;
        }

        // The culprit lies here...
        else if (strstr(config, ":")) {
            newCfg.values[newCfg.valuesSize][valuesPtr] = (char**)malloc(1000);

            char * split = strtok(config, ":");
            newCfg.values[newCfg.valuesSize][valuesPtr][0] = (char*)malloc(strlen(split)*sizeof(char));
            strcat(newCfg.values[newCfg.valuesSize][valuesPtr][0], split);

            split = strtok(NULL, ":");
            newCfg.values[newCfg.valuesSize][valuesPtr][1] = (char*)malloc(sizeof(split)*sizeof(char));
            strcat(newCfg.values[newCfg.valuesSize][valuesPtr][1], split);
            valuesPtr  ;
        }

        if (nextLine) *nextLine = '\n';
        config = nextLine ? (nextLine 1) : NULL;
    }

    (configIsMalloc==1) ? free(config) : NULL;
    return newCfg;
}

config.h defines the struct for storing config information C (config.h):

#ifndef CONFIG_H
#define CONFIG_H

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

struct Config {
char *** values;
int valuesSize;
};

struct Config read_config(char * cfg);

#endif

This contains information for the config reader to pick up This is read from a file in my program test-config:

{
ID:001
TITLE:Russian Spy Infiltration
DESCRIPTION:Those darn russian spies have done it again.
}

{
ID:002
TITLE:American Enthusiasts
DESCRIPTION:America!!!!!
}

The error that prints


{
ID:001
TITLE:Russian Spy Infiltration
DESCRIPTION:Those darn russian spies have done it again.
}
{
ID:002
malloc(): corrupted top size
fish: Job 1, './bm' terminated by signal SIGABRT (Abort)

EDIT: Instead of using sizeof(), I replaced them with strlen()

CodePudding user response:

        newCfg.values[newCfg.valuesSize][valuesPtr][0] = (char*)malloc(sizeof(split)*sizeof(char));

Why sizeof(split)? That's the same as sizeof(char*), which is obviously wrong. Did you mean to use strlen?

CodePudding user response:

Also, given `

struct Config {
char *** values;
int valuesSize;
};

and

char * config;

this line has two problems:

newCfg.values = (char****)malloc(sizeof(char****)*sizeof(config));`

First, sizeof(config) is the size of the pointer, not what it points to (and it points to a char of size one...). You probably wanted strlen(). Maybe.

And you are using sizeof(char****) even though values is a char ***. That won't cause a problem with the size on most systems, but it's still wrong. And if you follow the pattern, it will cause serious problems with smaller numbers if *s.

And many would say there's a third problem - you don't cast the return value from malloc() in C.

  • Related