Получение ошибки выделения памяти в памяти с поврежденным верхним размером - PullRequest
1 голос
/ 19 июня 2019

Я пишу программу на языке C, которая обрабатывает данные слоев tenorflow-keras и осуществляет прямое распространение для вычисления выходных нейронных сетей. Я должен интегрировать нейронные сети во встроенную систему, поэтому я должен реализовать простое умножение матриц в C. Я не являюсь экспертом в этом языке, и я получаю странное поведение при выделении освобождающей памяти. Если я использую prinf до выделения памяти, все работает, но если я не использую его, моя программа по какой-то причине прерывается, и я получаю эту ошибку: malloc(): corrupted top size. Я делаю распределение памяти плохим способом? Что я могу изменить, чтобы предотвратить такое поведение?

#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;
}

Моя программа зависит от исходного файла, поэтому вот данные о них: 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

Спасибо за ваше время!

1 Ответ

3 голосов
/ 19 июня 2019

Помните, что функция malloc принимает размер в байт для выделения, что означает, что распределение, например, malloc(unit), будет неправильным.

Youделайте это правильно в некоторых местах, где вы умножаете количество элементов на размер шрифта, но не в других местах.Вам нужно умножить на все мест.

Например,

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

должно быть

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

Есть несколько мест, где вы делаете этоошибка.

Из-за этого вы не выделяете достаточно памяти и выходите за пределы выделенной памяти.Это приводит к неопределенному поведению .В вашем конкретном случае вы, кажется, перезаписываете некоторые внутренние данные, используемые распределителем памяти, что приводит к проблемам при попытке использовать распределитель снова (например, когда вы free память).

Также обратите внимание, что вC не следует разыгрывать malloc.

...