我正在研究一些代码,这些代码用随机值初始化几个内存块。稍后,我将使用这些内存块作为神经网络中权重和偏差的矩阵,但这不是这个问题的重点。
我有两段代码(代码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;
}