成员长度可变的结构会导致“细分错误11”

时间:2018-08-29 21:28:10

标签: c segmentation-fault structure

我正在研究一些代码,这些代码用随机值初始化几个内存块。稍后,我将使用这些内存块作为神经网络中权重和偏差的矩阵,但这不是这个问题的重点。

我有两段代码(代码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;
}

0 个答案:

没有答案