Reputation: 489
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
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