Я работаю над кодом, который инициализирует пару блоков памяти со случайными значениями. Я буду использовать эти блоки памяти в качестве матриц для весов и смещений в нейронной сети позже, но это не главное в этом вопросе.
У меня есть две части кода (код A и код B), который делает одно и то же, а именно: инициализирует блок памяти случайными значениями. Обе части кода компилируются просто отлично, однако, когда я выполняю код B, я получаю ошибку ошибки сегментации 11, и код перестает выполняться. Код B работает со структурой переменной длины, и я считаю, что это создает проблему. Однако я не знаю, как это исправить.
Мой вопрос: Кто-нибудь знает, в чем причина проблемы и как ее исправить? Мне бы очень хотелось, чтобы код B работал, так как это удобно в коде позже. Я вставил обе части кода ниже. Система, в которой я тестировал этот код, - macOS.
Любая помощь будет принята с благодарностью!
Код A:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define DEBUG
/*
Function prototypes
*/
void init_rand(float *p, int size);
int main(int argc, char const *argv[])
{
int neurons [] = {10,10,10}; // use this array to define the neuralnet
int layers = sizeof(neurons)/sizeof(int); // this calculates the amount of layers in the neuralnet (i.e. the amount of members in the array 'neurons')
// array of pointers for the memory given by malloc
float *pwl[layers];
float *pbl[layers];
float *pzl[layers];
float *pal[layers];
for (int i = 1; i < layers; i++) // create memory for the matrices and assign the start adress of each matrix to the pointers
{
pwl[i] = (float *)malloc(neurons[i]*neurons[(i-1)]*sizeof(float));
pbl[i] = (float *)malloc(neurons[i]*sizeof(float));
pzl[i] = (float *)malloc(neurons[i]*sizeof(float));
pal[i] = (float *)malloc(neurons[i]*sizeof(float));
}
for (int i = 1; i < layers; i++) // initialize the weights and the biases with random values
{
init_rand(pwl[i], neurons[i]*neurons[i-1]);
init_rand(pbl[i], neurons[i]);
}
return 0;
}
/*
Random generator with a gaussian distribution. Mean = 0, Variance = 1
*/
double gaussrand()
{
static double V1, V2, S;
static int phase = 0;
double X;
if(phase == 0)
{
do
{
double U1 = (double)rand() / RAND_MAX;
double U2 = (double)rand() / RAND_MAX;
V1 = 2 * U1 - 1;
V2 = 2 * U2 - 1;
S = V1 * V1 + V2 * V2;
} while(S >= 1 || S == 0);
X = V1 * sqrt(-2 * log(S) / S);
} else
X = V2 * sqrt(-2 * log(S) / S);
phase = 1 - phase;
return X;
}
/*
This function initializes a float array with random gaussian distributed numbers
*/
void init_rand(float *p, int size)
{
for (int i = 0; i < size; i++, p++)
{
*p = (float)gaussrand();
#ifdef DEBUG
printf("%d:*p = %f\n", i, *p); //
#endif
}
}
Код B:
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#define DEBUG
struct neuralnet
{
int struct_size;
float *pwl[0];
float *pbl[0];
float *pzl[0];
float *pal[0];
};
/*
Function prototypes
*/
void init_rand(float *p, int size);
struct neuralnet* create_neuralnet(struct neuralnet* pnet, int layers);
int main(int argc, char const *argv[])
{
int neurons [] = {10,10,10}; // use this array to define the neuralnet
int layers = sizeof(neurons)/sizeof(int); // this calculates the amount of layers in the neuralnet
struct neuralnet *pnet; // create a struct neuralnet pointer
pnet = create_neuralnet(pnet, layers); // this function will create a neuralnet structure with variable size members
for (int i = 1; i < layers; i++) // create memory for the matrices and assign the start adress of each matrix to the pointers
{
pnet->pwl[i] = (float *)malloc(neurons[i]*neurons[(i-1)]*sizeof(float));
pnet->pbl[i] = (float *)malloc(neurons[i]*sizeof(float));
pnet->pzl[i] = (float *)malloc(neurons[i]*sizeof(float));
pnet->pal[i] = (float *)malloc(neurons[i]*sizeof(float));
}
for (int i = 1; i < layers; i++) // initialize the weights and the biases with random values
{
init_rand(pnet->pwl[i], neurons[i]*neurons[i-1]);
init_rand(pnet->pbl[i], neurons[i]);
}
return 0;
}
/*
Random generator with a gaussian distribution. Mean = 0, Variance = 1
*/
double gaussrand()
{
static double V1, V2, S;
static int phase = 0;
double X;
if(phase == 0)
{
do
{
double U1 = (double)rand() / RAND_MAX;
double U2 = (double)rand() / RAND_MAX;
V1 = 2 * U1 - 1;
V2 = 2 * U2 - 1;
S = V1 * V1 + V2 * V2;
} while(S >= 1 || S == 0);
X = V1 * sqrt(-2 * log(S) / S);
} else
X = V2 * sqrt(-2 * log(S) / S);
phase = 1 - phase;
return X;
}
/*
This function initializes a float array with random gaussian distributed numbers
*/
void init_rand(float *p, int size)
{
for (int i = 0; i < size; i++, p++)
{
*p = (float)gaussrand();
#ifdef DEBUG
printf("%d:*p = %f\n", i, *p); //
#endif
}
}
/*
This function creates the structure with members of variable length
*/
struct neuralnet* create_neuralnet(struct neuralnet *pnet, int layers)
{
pnet = (struct neuralnet *)malloc(sizeof(*pnet) + sizeof(float *) * layers * 4);
return pnet;
}