dqmis
dqmis

Reputation: 489

Getting memory memory allocation error with corrupted top size

I am writing a C language program that process tensorflow-keras layers data and makes forward propagation to calculate neural nets output. I have to integrate neural nets to embedded system so I have to implement simple matrix multiplication i C. I am not an expert in this language and I am getting weir behavior while allocating an releasing memory. If I am using prinf before memory allocation, everything works, but if I don't use it, my program breaks for some reason and I am getting this error: malloc(): corrupted top size. Am I making memory allocation in bad way? What can I change to prevent this behavior?

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

typedef struct
{
    int layer_count;
    int input, unit;
    float *b;
    float **w;
} layer;

void init_layer_types(layer* l, int layer_count, int input, int unit)
{
    l->input = input;
    l->unit = unit;
    l->layer_count = layer_count;

    l->w = (float **)malloc(input * sizeof(float *));
    for (int i=0; i < input; i++)
        l->w[i] = (float *)malloc(unit * sizeof(float));

    l->b = (float *)malloc(unit * sizeof(float));
}

void read_layers(int layers_count, layer network[]) {
    FILE* file = fopen("layers.txt", "r");
    int input, unit;
    float val;
    for (int i = 0; i < layers_count; i++) {
        layer l;
        fscanf(file, "%d", &input);
        fscanf(file, "%d", &unit);
        init_layer_types(&l, i, input, unit);

        for (int j = 0; j < input; j++) {
            for (int k = 0; k < unit; k++) {
                fscanf(file, "%f", &val);
                l.w[j][k] = val;
            }
        }
        for (int j = 0; j < unit; j++) {
            fscanf(file, "%f", &val);
            l.b[j] = val;
        }
        network[i] = l;
    }
}

void dot(int m1, int m2, int n1, int n2, float **mat1, float **mat2, float **res)
{
    for (int i = 0; i < m1; i++) {
        for (int j = 0; j < n2; j++)
        {
            res[i][j] = 0;
            for (int x = 0; x < m2; x++)
                res[i][j] += mat1[i][x] * mat2[x][j];
        }
    }
}

void add(float **output, float *b, int m, int n)
{
    for (int i = 0; i < m; i++)
        for (int j = 0; j < n; j++)
            output[i][j] += b[i];
}

void read_inputs(int dim, float **inputs) {
    float val;
    FILE* file = fopen("inputs.txt", "r");
    for (int i = 0; i < dim; i++) {
        fscanf(file, "%f", &val);
        inputs[0][i] = val;
    }
}

void free_memory(int n, float **arr) {
    for (int i = 0; i < n; i++)
        free(arr[i]);
    free(arr);
    arr = NULL;
}

float **get_arr(int input_dim, int unit) {
    float **output = (float **)malloc(input_dim * sizeof(float *));
    for (int j = 0; j < input_dim; j++)
        output[j] = (float *)malloc(unit);
    return output;
}

int main() {
    const int input_dim = 1;
    const int input_count = 5;
    const int layer_count = 3;

    float **inputs = get_arr(input_dim, input_count);
    read_inputs(input_count, inputs);

    layer *network = (layer *)malloc(layer_count * sizeof(layer));
    read_layers(layer_count, network);

    float  **output;
    printf("Processing\n"); // <-- Here if I delete this line, I get memory allocation error.
    for (int i = 0; i < layer_count; i++)
    {
        output = get_arr(input_dim, network[i].unit);

        dot(input_dim, network[i].input, network[i].input, network[i].unit, inputs, network[i].w, output);
        add(output, network[i].b, input_dim, network[i].unit);

        free_memory(input_dim, inputs);
        inputs = output;
    }
    float num = *(inputs[0]);
    free_memory(input_dim, inputs);
    printf("%f", num);
    return 0;
}

My program is source file dependent, so here are data of them: layers.txt:

5 16
-0.27510703 0.05656046 0.21719019 0.36794823 -0.45897833 -0.15796176 0.42044222 0.12223288 -0.4054776 0.78101534 -0.2743374 -0.038984317 0.21881248 -0.57430464 0.06383126 -0.7321343 -0.27794576 -0.25287467 -0.586286 -0.057798754 -0.097728394 -0.16848974 -0.31734765 0.5382229 -0.19734482 -0.12539126 0.80764467 0.83615685 -0.15496157 0.6195798 -0.9146123 -0.57317895 0.059357792 0.05658521 -0.27737 -0.13202512 -0.31854483 0.2181433 -0.25090697 0.4077587 -0.5032105 0.041977283 0.03668945 0.3296285 0.19465968 0.420567 -0.70456696 -0.43721324 -0.3233525 0.17888355 -0.38667187 0.14075014 0.041260455 0.018714897 -0.565683 0.41157398 0.09909809 0.37904713 0.6497243 -0.19682685 -0.55571586 0.034314968 -0.69701445 -0.3313689 0.34335998 0.8097565 -0.5070784 0.4980565 -0.00498956 1.0258771 0.022312356 0.16200699 0.2964861 -0.15127556 0.6075885 0.012937768 0.63023937 0.37498713 -1.3245078 -0.07527774
0.7297894 0.88037413 -0.49263608 0.88363385 0.7770243 0.9019361 0.57204115 0.94174325 0.7811348 0.3338186 0.6115855 0.9348049 0.98463 0.74922246 -0.2442382 0.7401446
16 16
0.5294986 0.095209315 0.5816423 0.011750876 0.79768986 0.18347172 0.5230593 -0.20458926 0.03238925 0.7263444 0.19537736 0.51469505 0.38453174 0.4792065 0.47070476 0.48203093 0.6408747 0.20587757 0.87248856 0.51753175 0.19367562 0.5328166 0.6011898 -0.9065597 0.95500827 0.33368462 0.53764784 0.45068842 0.12343783 -0.93090314 0.009520332 0.84407306 -0.4930213 -0.60485965 -0.113633305 -0.20889078 -1.1993133 -0.59244674 -0.14670648 0.5882502 -0.44252092 -0.9068741 -0.47101536 -0.6771671 -0.57774156 0.3202908 -0.6125743 -0.19555524 0.34589607 0.48220173 0.887751 -0.010264315 -0.53484684 0.9223027 -0.116944976 0.3552805 0.57485306 1.1548213 0.73101723 0.024920506 0.758325 0.33818895 0.46289825 0.75641644 0.5973245 0.58425486 0.6186228 0.27397043 -0.16205522 0.24053968 0.14349774 0.0682401 0.78229904 0.53935903 0.06586165 -0.036975164 0.14868408 0.114033416 0.21479316 0.33285123 0.82021 0.7476087 0.53433895 0.18636973 -0.004250426 0.80443674 0.35212353 -0.99279344 0.09624279 0.22507294 0.1551801 0.4401552 0.4344537 -1.0609607 0.2112829 0.73665375 0.30300483 0.43053505 -0.075404234 -0.46463633 -0.63602394 0.11983294 -0.1700229 0.12950262 0.037001535 0.14967114 0.2236458 0.23652838 -0.074841894 0.4731138 -0.1891633 0.5675689 0.5004651 0.7590372 0.3406028 -0.30780622 -0.4056706 0.054417405 0.014160816 -0.502301 0.6902765 0.5627833 0.6560702 0.14820565 0.44759235 -0.4517361 0.24475953 0.19302326 0.17013979 0.7032596 0.59683084 0.6487092 0.13578065 0.9571763 0.3489112 0.24147744 0.294642 0.91326237 0.02771005 0.30833304 0.8724447 -0.30238068 0.8733717 0.60625494 0.6640253 0.12542762 0.3752495 -0.14965096 -0.21784364 0.6297658 -0.1163313 0.14957857 0.59309405 0.029121447 0.22690158 -0.24634236 0.08391688 0.4665475 0.43288168 0.04094743 0.550001 -0.030953215 0.72441626 -0.5303838 -0.6599007 0.28969297 0.13298538 -0.97688687 0.10630749 0.7048332 -0.020065783 0.45250762 0.65564346 0.36419603 -0.15683183 0.56276035 0.13720869 0.5241819 0.32492644 0.41968134 0.0985914 0.8151626 0.16679804 -0.37237772 0.20443702 0.54484195 0.61047757 -0.29266858 0.83509314 -0.42326364 0.8025571 0.9248121 0.84348476 0.9041855 0.5863141 0.6110747 1.1242607 1.1184481 -0.27281645 0.122819185 0.62381345 0.65988976 0.6341375 -0.45514598 0.68389523 0.28733313 0.7390246 0.9125664 0.3933753 0.6393983 0.13370913 -0.5635324 0.23211549 0.5146912 0.14429328 -0.21532854 0.5479508 0.16717906 0.48443708 -0.07323354 0.3086167 -0.11754378 0.2828258 0.6764059 -0.68566364 0.14362451 -0.26707077 -0.053668447 -0.7462183 -0.71973497 -0.43526867 0.5410068 0.024889803 -0.5076304 0.062299147 -0.3323771 -0.6676218 0.08483551 -0.5460029 -0.66296375 0.6821926 0.301253 0.5014378 0.5700288 0.50235826 0.2884027 -0.710421 0.5061369 0.044829175 0.18046197 0.7125541 -0.5425324 0.33107722 0.16374299 0.24497494 0.33329406
0.67616004 0.51669836 0.6583131 0.24366198 0.1501881 0.80439085 -0.16105098 0.011128932 0.5884628 0.77304965 0.54262626 -0.19401886 0.66081685 0.04697459 0.8041494 0.6982975
16 1
0.9814956 0.8053132 0.5269977 -0.8047956 -1.6299891 0.80752444 -0.8163326 -0.6561919 0.8894982 0.78555495 1.0655055 -0.47944012 1.1637385 -0.3714269 0.85063654 1.0498714
0.40419745

inputs.txt:

30.7 3.864 3.866 3.867 3.864

Thanks for yours time!

Upvotes: 2

Views: 2621

Answers (1)

Some programmer dude
Some programmer dude

Reputation: 409384

Remember that the malloc function takes the size in bytes to allocate, which means an allocation like e.g. malloc(unit) will be incorrect.

You do it correctly in some places where you multiply the number of elements to allocate with the size of the type, but not in other places. You need to multiply in all places.

For example

output[j] = (float *)malloc(unit);

should be

output[j] = malloc(unit * sizeof *output[j]);

There are a few places you do this mistake.

Because of this, you don't allocate enough memory, and will go out of bounds of the allocated memory. That leads to undefined behavior. In your specific case you seem to overwrite some internal data used by the memory allocator, leading to problems when you attempt to use the allocator again (for example when you free the memory).

Also note that in C you should not cast the result of malloc.

Upvotes: 4

Related Questions