求调教:C的struct,数组引用,与指针混乱(又坏掉了)

来源:百度文库 编辑:超级军网 时间:2024/04/29 20:40:09


想了想,就发这儿吧。
我这里有多层次的结构体与数组引用。现在在设置值之后有点毛病。
首先我写了一个用来做向量运算的“类”(我在拿C当C++用)……
  1. struct AnnVec {
  2.         long    size;
  3.         double *content;
  4. };
复制代码
然后是神经网络的节点
  1. struct AnnNode {
  2.         double         output;
  3.         struct AnnVec *weight;
  4.         long           size;
  5.         long            inited;
  6. };
复制代码
然后是神经网络的层
  1. struct AnnLayer {
  2.         long             size;
  3.         long             inputSize;
  4.         double         (*triggerFunc)(double);
  5.         struct AnnNode **nodes;
  6.         struct AnnVec   *input;
  7.         struct AnnVec   *output;
  8.         long             inited;
  9. };
复制代码
问题出在:首先我建一个简单的、有两个节点、输入尺寸为4的层:
  1. struct AnnLayer *layer = ann_layer_new(4,2);
  2. layer->triggerFunc = logistic;
  3. ann_layer_init(layer,1);
复制代码
可以观察到:

  1. (gdb) p layer->nodes[0]
  2. $1 = (struct AnnNode *) 0x603050
  3. (gdb) p layer->nodes[0]->weight
  4. $3 = (struct AnnVec *) 0x603080
复制代码
然后设置输入
  1. struct AnnVec *input1 = ann_vec_new(4);
  2. double data1[4] = {1,2,3,4};
  3. input1->content = data1;
复制代码
发现节点0的地址改变了!
  1. (gdb) p layer->nodes[0]
  2. $5 = (struct AnnNode *) 0x603150
  3. (gdb) p layer->nodes[0]->weight
  4. $7 = (struct AnnVec *) 0x7fffffffe0e0
复制代码
而且再访问节点0的内容,发现inited属性自动地变成了奇怪的值(应当只是1或0):

  1. (gdb) p layer->nodes[0]->inited
  2. $9 = 49
复制代码
并且,再访问节点0的weight的内容,会导致segfault:
  1. (gdb) p layer->nodes[0]->weight->content[0]
  2. Cannot access memory at address 0x4000000000000000
复制代码
这是为什么?!!

想了想,就发这儿吧。
我这里有多层次的结构体与数组引用。现在在设置值之后有点毛病。
首先我写了一个用来做向量运算的“类”(我在拿C当C++用)……
  1. struct AnnVec {
  2.         long    size;
  3.         double *content;
  4. };
复制代码然后是神经网络的节点
  1. struct AnnNode {
  2.         double         output;
  3.         struct AnnVec *weight;
  4.         long           size;
  5.         long            inited;
  6. };
复制代码然后是神经网络的层
  1. struct AnnLayer {
  2.         long             size;
  3.         long             inputSize;
  4.         double         (*triggerFunc)(double);
  5.         struct AnnNode **nodes;
  6.         struct AnnVec   *input;
  7.         struct AnnVec   *output;
  8.         long             inited;
  9. };
复制代码问题出在:首先我建一个简单的、有两个节点、输入尺寸为4的层:
  1. struct AnnLayer *layer = ann_layer_new(4,2);
  2. layer->triggerFunc = logistic;
  3. ann_layer_init(layer,1);
复制代码可以观察到:

  1. (gdb) p layer->nodes[0]
  2. $1 = (struct AnnNode *) 0x603050
  3. (gdb) p layer->nodes[0]->weight
  4. $3 = (struct AnnVec *) 0x603080
复制代码然后设置输入
  1. struct AnnVec *input1 = ann_vec_new(4);
  2. double data1[4] = {1,2,3,4};
  3. input1->content = data1;
复制代码发现节点0的地址改变了!
  1. (gdb) p layer->nodes[0]
  2. $5 = (struct AnnNode *) 0x603150
  3. (gdb) p layer->nodes[0]->weight
  4. $7 = (struct AnnVec *) 0x7fffffffe0e0
复制代码而且再访问节点0的内容,发现inited属性自动地变成了奇怪的值(应当只是1或0):

  1. (gdb) p layer->nodes[0]->inited
  2. $9 = 49
复制代码并且,再访问节点0的weight的内容,会导致segfault:
  1. (gdb) p layer->nodes[0]->weight->content[0]
  2. Cannot access memory at address 0x4000000000000000
复制代码这是为什么?!!
论坛代码都用不熟练的只能仰望了……
复制代码
struct AnnLayer *self = (struct AnnLayer *) malloc(sizeof(NULL));

分配内存太少了吧,为啥不是sizeof(struct AnnLayer )?
aerol 发表于 2011-1-5 18:02

唉?!对啊!!![:a3:]
我想起来是怎么回事了!
我做过一次修改,看来改错位置了!!:L
self->nodes = calloc(sz,sizeof(struct AnnNode*));
最好也加上类型转换(struct AnnNode **)
aerol 发表于 2011-1-5 18:21

刚发现C有typedef这个东西……我写struct XXX都快手抽筋了:L
VC不是有个番茄助手神马的么?可以简化输入什么的……
{:qiliang:}
45度仰视LZ和4L强人
C新手来膜拜一下…
forgottenlove 发表于 2011-1-6 09:10

不用VC。
我用gcc和make。
看不懂啊。。。。。。看不懂啊
用gcc和make的,膜拜一下
我今天才有机会上网,才看到站内短信……来晚了……
aerol 发表于 2011-1-5 18:02


    一眼即知,高人啊…
forgottenlove 发表于 2011-1-6 09:10


    LZ用的是Gnu的gcc编译器,在Fedora平台,真和Vc没关系呢…
LPC2103 发表于 2011-1-6 19:37

桃巴酱一定是用马甲偷偷上来,回答完问题,然后装作来晚的样子:lol
LPC2103 发表于 2011-1-6 19:44

只为过二级C的路过,表示各位是大侠,小的水平低……
{:cha:}
jiandingzhe 发表于 2011-1-6 21:33


    不是,你误会了,那位是真的高人,不是我这样的半桶水,我只帮你勉强解决过一次问题……
{:lei:}2级vf滚过……
jiandingzhe 发表于 2011-1-6 21:33


    说正经的,我忽然想到有本经典的国外书…C和指针,乃可以借来好好看看,csdn上有pdf下……
LPC2103 发表于 2011-1-8 14:53

很好看的样子,多谢巴酱!
LPC2103 发表于 2011-1-8 14:53

另外,我发现Glib是个不错的库,比C标准库好使,里面有很多有趣的小玩意。
比如像Perl的Getopt::Long那样的解参数用的系统,非常简洁。还有显式地指定长度的类型(像gint32、gint64)、在be和le之间转换的宏什么的……
其实qt的那个库也还可以,当然前途黯淡了点…表鄙视我就可以了…
表示压力很大啊……
要是去年你来问我这问题 或许我还记着~~
Spica 发表于 2011-1-8 16:02


    我用小屏幕不给力的手机同时看这个和四代压力才叫大……
复制代码
复制代码这TNND是咋回事?!咋跑了?!
回复 29# jiandingzhe


    手里没有编译器,不过
all_sample  = calloc(*sample_num, sizeof(AnnVec*));
应该是
all_sample  = calloc(*sample_num, sizeof(struct AnnVec *));
吧,

把函数里所有的Annvec 换成 struct Annvec试试
复制代码
回复 31# jiandingzhe


    初始化函数也变了吗
回复 32# aerol

当然修改过了
回复 33# jiandingzhe

可以把初始化函数也发上来看看,其他的似乎都没什么错
not again..=3=
复制代码


为啥不用g++捏,这种东西适合c++

为啥不用g++捏,这种东西适合c++
废土行者 发表于 2011-1-22 19:21

正好练习一下C
正在学c++的物理废柴路过围观下……然后,神经网络算法到底是神马东西啊
zhanyuheng 发表于 2011-1-24 15:37

神经网络其实用C++更好做。
就是一个输入向量,弄一堆节点对象,每个节点对输入向量的每个元素都有个权重,然后再弄一个非线性的变换函数(最常用S形),得到一个输出值。然后这样就可以垒成几层……