指向数组的C指针未赋值

时间:2016-01-27 01:24:57

标签: c arrays heap variable-assignment

我正在研究神经网络,所以我有非常大的数据结构。因此,我正在使用指向堆中数组的指针。我有一个总是分配0

的赋值语句

没有任何东西超出范围,一切都是double

类型

代码段如下:

        for( j = 0 ; j < NumHidden ; j++ ) {    /* compute hidden unit activations */
                  *(SumH + p + j) = *(WeightIH + 0) ;
                  for( i = 0 ; i <= NumInput ; i++ ) {
                      temp1 = *(Input + game + 0 + i) * *(WeightIH + i + j) ;
                      temp2 = *(Input + game + 1 + i) * *(WeightIH + i + j) ;
                      *(SumH + p + j) += temp1 - temp2 ;
                  }
                  *(Hidden + p + j) = 1.0/(1.0 + exp(-*(SumH + p + j))) ;
              }

在gdb中我可以证明这些值是非零的:

117  temp1 = *(Input + game + 0 + i) * *(WeightIH + i + j) ;
(gdb) p *Input
$1 = 0.75454545500000003
(gdb) p *WeightIH
$2 = 0.5
(gdb) n
118                       temp2 = *(Input + game + 1 + i) * *(WeightIH + i + j) ;
(gdb) p temp1
$3 = 0

...但正如您所看到的,temp1在赋值后等于零。我错过了什么?

更新

按要求:

Breakpoint 1, main () at nn.c:117
117                       temp1 = *(Input + game + 0 + i) * *(WeightIH + i + j) ;
(gdb) p *(WeightIH + i + j)
$1 = 0.5
(gdb) p *(Input + game + 0 + i)
$2 = 0.75454545500000003

以下是整个代码:

一些伪代码:

将所有输入读入3d数组

定义所有结构(都是正确的,没有超出界限)

循环模式数

循环游戏数量(这是运动模型)

计算激活值

计算输出值

计算错误

回传播

更新权重

    /*******************************************************************************
*    nn.c   1.0                                       � JOHN BULLINARIA  2004  *
*******************************************************************************/

/*      To compile use "cc nn.c -O -lm -o nn" and then run using "./nn"       */
/*      For explanations see:  http://www.cs.bham.ac.uk/~jxb/NN/nn.html       */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <fcntl.h>

#define NUMPAT 101
#define NUMIN  24
#define NUMHID 100
#define NUMOUT 55

#define rando() ((double)rand()/(RAND_MAX+1))

int main() {
    int    i, j, k, p, np, op, ranpat[NUMPAT], epoch,  game;
    int    NumPattern = NUMPAT, NumInput = NUMIN, NumHidden = NUMHID, NumOutput = NUMOUT;
    double temp1, temp2;

    double *Input = (double *)malloc(NumOutput*2*NumInput*sizeof(double));

    char line[128];
    double num;

    FILE *csvFile = fopen("inputs.csv", "r");
    int oned_count = 0;
    int twod_count = 0;
    int threed_count = 0;
    int count = 0;

    if (csvFile){
      char *token;
      while (fgets(line, 1024, csvFile)){
        token = strtok(&line[0], ",");
        while(token){
          num = atof(token);
          *(Input + oned_count + twod_count + threed_count) = num;
          token = strtok(NULL, ",");
          threed_count++;
        }
        count++;
        if ((count % 2) == 0){
          oned_count++;
        }
        twod_count++;
        if (twod_count == 2){
          twod_count = 0;
        }
      }
      fclose(csvFile);
    }

    double Target[55] = {-5 ,25,    -3, 2   ,5  ,17,    10, 10  ,3  ,-8,    11  ,-2,    -5, 17  ,4  ,4  ,2  ,12,    5   ,-11    ,-4,    -9  ,13,    -1, 5   ,7  ,5  ,4, 8   ,12 ,-13    ,-2, 3  ,34,    -19 ,6, 7   ,-9 ,14,    4   ,3  ,-17    ,3, 6   ,-5,    -2, -1, -7, 11, -1, 15, -7  ,7  ,19,    1};

    double *SumH =(double *)malloc(NumPattern*NumHidden*sizeof(double));
    double *WeightIH =(double *)malloc(NumInput*NumHidden*sizeof(double));
    double *Hidden =(double *)malloc(NumPattern*NumHidden*sizeof(double));
    double *SumO =(double *)malloc(NumPattern*NumOutput*sizeof(double));
    double *WeightHO =(double *)malloc(NumHidden*NumOutput*sizeof(double));
    double *Output =(double *)malloc(NumPattern*NumOutput*sizeof(double));
    double *DeltaWeightIH =(double *)malloc(NumInput*NumHidden*sizeof(double));
    double *DeltaWeightHO = (double *)malloc(NumHidden*NumOutput*sizeof(double));

    double DeltaO[NumOutput];
    double SumDOW[NumHidden];
    double DeltaH[NumHidden];

    double Error, eta = 0.10, alpha = 0.9;

    //double temps[24] = {-0.901337 -0.872058   -0.765912   -0.904485   -1.01524    ,-1.00116,  -1.02088,   -0.849757,  -0.777824,  -0.967258   ,-1.02125,  -0.773202,  -0.622447   ,-0.576088  ,-0.76714,  -0.741354   ,-0.669561, -0.606497   ,-0.670834  ,-0.85477,  -0.980444,  -1.00685,   -0.0365572, -0.000114586};

    for( j = 0 ; j < NumHidden ; j++ ) {    /* initialize WeightIH and DeltaWeightIH */
        for( i = 0 ; i < NumInput ; i++ ) {
            *(DeltaWeightIH + i + j) = 0;
            // *(WeightIH + i) = test_weights[i] ;
            *(WeightIH + i + j) = .5 ;
        }
    }

    for( k = 0 ; k < NumOutput ; k ++ ) {    /* initialize WeightHO and DeltaWeightHO */
        for( j = 0 ; j < NumHidden ; j++ ) {
            *(DeltaWeightHO + j + k) = 0.0 ;
            *(WeightHO + j + k) = 1;
        }
    }

    for( epoch = 0 ; epoch < 500000 ; epoch++) {    /* iterate weight updates */
        for( p = 0 ; p < NumPattern ; p++ ) {    /* randomize order of individuals */
            ranpat[p] = p ;
        }
        for( p = 0 ; p < NumPattern ; p++) {
            np = rand() % NUMPAT ;
            op = ranpat[p] ;
            ranpat[p] = ranpat[np] ;
            ranpat[np] = op ;
        }
        Error = 0.0 ;
        for( np = 0 ; np < NumPattern ; np++ ) {    /* repeat for all the training patterns */
            p = ranpat[np];
            for (game = 0; game < 55; game++){
              for( j = 0 ; j < NumHidden ; j++ ) {    /* compute hidden unit activations */
                  *(SumH + p + j) = *(WeightIH + 0) ;
                  for( i = 0 ; i < NumInput ; i++ ) {
                      temp1 = *(Input + game + 0 + i) * *(WeightIH + i + j) ;
                      temp2 = *(Input + game + 1 + i) * *(WeightIH + i + j) ;
                      *(SumH + p + j) += temp1 - temp2 ;
                  }
                  *(Hidden + p + j) = 1.0/(1.0 + exp(-*(SumH + p + j))) ;
              }
              for( k = 0 ; k < NumOutput ; k++ ) {    /* compute output unit activations and errors */
                  *(SumO + p + k) = *(WeightHO + 0 + k) ;
                  for( j = 0 ; j < NumHidden ; j++ ) {
                      *(SumO + p + k) += *(Hidden + p + j) * *(WeightHO + j + k) ;
                  }
                  *(Output + p + k) = 1.0/(1.0 + exp(-*(SumO + p + k))) ;   /* Sigmoidal Outputs */
                  //*(Output + p + k) = (exp(*(Output + p + k)) - exp(-*(Output + p + k))) / (exp(*(Output + p + k)) + exp(-*(Output + p + k))); //TANH
                  //*(Output + p + k) = (2.0/(1.0 + exp(-*(SumO + p + k)))) - 1 ; //bipolar sigmoid
                  //*(Output + p + k) = .5 * (1 + 1.0/(1.0 + exp(-*(SumO + p + k)))) * (1 - 1.0/(1.0 + exp(-*(SumO + p + k)))); //derivative sigmoid
                  //*(Output + p + k) = .5 * (1 + ((2.0/(1.0 + exp(-*(SumO + p + k)))) - 1)) * (1 - ((2.0/(1.0 + exp(-*(SumO + p + k)))) - 1)); //derivative bioolar sigmoid
  /*              Output[p][k] = SumO[p][k];      L
ear Outputs */
                  Error += 0.50 * (Target[game] - *(Output + p + k)) * (Target[game] - *(Output + p + k)) ;   /* SSE */
                  //Error -= ( Target[game] * log( *(Output + p + k) ) + ( 1.0 - Target[k] ) * log( 1.0 - *(Output + p + k) ) ) ;
                  DeltaO[k] = (Target[game] - *(Output + p + k)) * *(Output + p + k) * (1.0 - *(Output + p + k)) ;   /* Sigmoidal Outputs, SSE */
                  //DeltaO[k] = (exp(Target[game]) - exp(-*(Output + p + k))) / (exp(Target[game]) + exp(-*(Output + p + k)))
                  //DeltaO[k] = Target[k] - *(Output + p+k);
                  //DeltaO[k] = Target[game] - *(Output +p + k);
              }
              for( j = 0 ; j < NumHidden ; j++ ) {    /* 'back-propagate' errors to hidden layer */
                  SumDOW[j] = 0.0 ;
                  for( k = 0 ; k < NumOutput ; k++ ) {
                      SumDOW[j] += *(WeightHO + j + k) * DeltaO[k] ;
                  }
                  DeltaH[j] = SumDOW[j] * *(Hidden + p + j) * (1.0 - *(Hidden + p + j)) ;
              }
              for( j = 0 ; j < NumHidden ; j++ ) {     /* update weights WeightIH */
                  *(DeltaWeightIH + 0 + j) = eta * DeltaH[j] + alpha * *(DeltaWeightIH + 0 + j) ;
                  *(WeightIH + 0 + j) += *(DeltaWeightIH + 0 + j) ;
                  for( i = 0 ; i < NumInput ; i++ ) {
                      *(DeltaWeightIH + i + j) = eta * *(Input + game + 0 + i) * DeltaH[j] + alpha * *(DeltaWeightIH + i + j);
                      *(WeightIH + i + j) += *(DeltaWeightIH + i + j) ;
                  }
              }
              for( k = 0 ; k < NumOutput ; k ++ ) {    /* update weights WeightHO */
                  *(DeltaWeightHO + 0 + k) = eta * DeltaO[k] + alpha * *(DeltaWeightHO + 0 + k) ;
                  *(WeightHO + 0 + k) += *(DeltaWeightHO + 0 + k) ;
                  for( j = 0 ; j < NumHidden ; j++ ) {
                      *(DeltaWeightHO + j + k) = eta * *(Hidden + p + j) * DeltaO[k] + alpha * *(DeltaWeightHO + j + k) ;
                      *(WeightHO + j + k) += *(DeltaWeightHO + j + k) ;
                  }
              }
            }

        }
        //if( epoch%10 == 0 ){
          fprintf(stdout, "\nEpoch %-10d :   Error = %f\n", epoch, Error) ;
          // fprintf(stdout, "\nEpoch %-10d :   weight1 example = %f", epoch, *(WeightIH)) ;
          printf("Input weights:\n");
          printf("-------------------\n");
          for (i = 0; i < 24; i++){
            printf("%G\n", *(WeightIH + i + 100));
          }
          printf("Hidden weights:\n");
          printf("-------------------\n");
          for (i = 0; i < NumHidden; i++){
            printf("%G\n", *(WeightHO + i + 55));
          }

        //}
        if( Error < 0.0004 ) break ;  /* stop learning when 'near enough' */
    }


    return 1 ;
}

/*******************************************************************************/

2 个答案:

答案 0 :(得分:1)

temp1temp2int s .....

根据经验,将变量声明为它们所使用的最内层范围。

答案 1 :(得分:0)

这个问题让我感到困惑,因为我看不出什么是错的。我有两个想法要检查:

  1. 我认为行temp1 = *(Input + game + 0 + i) * *(WeightIH + i + j) ;是正确的,但是 - 只是为了笑 - 尝试添加另一组括号: temp1 =(*(输入+游戏+ 0 + i))*(*(WeightIH + i + j));

  2. 你可能会在那之前的某个地方弄到内存损坏(虽然我不知道在哪里)。 M.M是正确的,因为你所有的索引可能都是错误的。考虑如何构建二维数组,以及您尝试访问哪个元素 - 例如*(WeightIH + i + j) 访问&#39; line&#39;我,排&#39; j&#39; - 你需要将行索引与col长度相乘(或者相反,但是你喜欢,只是一致):*(WeightIH + i*NumHidden + j)。考虑到i = 1的行不是从索引1 + 0开始,但是在j的所有NumHidden元素完成之后,所以它从索引NumHidden + 0开始,等等。修复此问题,并尝试问题是否消失。 / p>