论坛首页 入门技术论坛

C语言--结构体中的指针

浏览 10686 次
该帖已经被评为新手帖
作者 正文
   发表时间:2009-12-06   最后修改:2009-12-11
今天来讨论一下C中的内存管理。

记得上周在饭桌上和同事讨论C语言的崛起时,讲到了内存管理方面
我说所有指针使用前都必须初始化,结构体中的成员指针也是一样
有人反驳说,不是吧,以前做二叉树算法时,他的左右孩子指针使用时难道有初始化吗
那时我不知怎么的想不出理由,虽然我还是坚信要初始化的

过了几天这位同事说他试了一下,结构体中的成员指针不经过初始化是可以用(左子树和右子树指针)
那时在忙着整理文档,没在意
今天抽空调了一下,结论是,还是需要初始化的。
而且,不写代码你是不知道原因的(也许是对着电脑久了IQ和记性严重下跌吧)
测试代码如下

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct student{
  char *name;
  int score;
  struct student* next;
}stu,*stu1; 

int main(){	
  stu.name = (char*)malloc(sizeof(char)); /*1.结构体成员指针需要初始化*/
  strcpy(stu.name,"Jimy");
  stu.score = 99;

  stu1 = (struct student*)malloc(sizeof(struct student));/*2.结构体指针需要初始化*/
  stu1->name = (char*)malloc(sizeof(char));/*3.结构体指针的成员指针同样需要初始化*/
  stu.next  = stu1;
  strcpy(stu1->name,"Lucy");
  stu1->score = 98;
  stu1->next = NULL;
  printf("name %s, score %d \n ",stu.name, stu.score);
  printf("name %s, score %d \n ",stu1->name, stu1->score);
  free(stu1);
  return 0;
}


写测试代码的过程中我明白了,同事所说的二叉树遍历算法中所用的左子树和右子树指针不需要初始化,其实是这样的,左子树和右子树指向的必须是二叉树节点类型的结构体指针(你填一个长度相同的指针也可以),而该结构体指针是需要初始化的(见注释2),也就是并没有通过malloc来分配内存,而是将另一个指针的值赋给它

顿时觉得挺无语的,确实,看了很多大学里的教材,对于二叉树的遍历等算法定义的结构体无非是以下形式
struct node{
  int data;
  struct node* lchild, rchild;
};

使用时都直接的
 struct node* root;
  root = (struct node*)malloc(sizeof(struct node));
  root->data = 3;

  struct node* nlchild;
  nlchild = (struct node*)malloc(sizeof(struct node));
  root->lchild = nlchild;
  nlchild->data = 2; 

  struct node* nrchild;
  nlrchild = (struct node*)malloc(sizeof(struct node));
  root->rchild = nrchild;
  nrchild->data = 4; 

这样子给人造成一种错觉好像结构体成员指针是不用初始化的。

可是,只要是指针,要使用它前就必须保证指针变量的值是一个有效的值;否则,它指向的内存一定是垃圾数据!
C语言的内存管理很重要,集魄力和麻烦于一身,看你自己的心态如何了。如果你积极的面对,你正在控制一切;如果你觉得烦躁,你正不得不控制一切。C仍旧是博大精深的语言,信C哥!

/*附加:仍旧是指针*/
  stu1 = (struct student*)malloc(sizeof(struct student));/*2.结构体指针需要初始化*/

这一句可能会有人把sizeof里边也填成struct student*
可以理解这样的行为,因为stu本来就是struct student*,可是这样子你就没有为结构体分配足够的内存,使用中会因为内存错误同样报错的。
当然,仅仅为结构体指针分配内存还不够,结构体成员指针仍然需要分配内存,如下
stu1->name = (char*)malloc(sizeof(char));
   发表时间:2009-12-07  
虽然有的地方是没必要,但顺手初始化一下是个好习惯。
0 请登录后投票
   发表时间:2009-12-11  
我觉得这个应该改为指针使用更好,并不涉及什么内存管理.
0 请登录后投票
   发表时间:2009-12-11  
Arath 写道
我觉得这个应该改为指针使用更好,并不涉及什么内存管理.


改了一下题目,现在如何?跟内存管理还是有些关系的,主要是指针
0 请登录后投票
   发表时间:2009-12-11  
lasombra 写道
Arath 写道
我觉得这个应该改为指针使用更好,并不涉及什么内存管理.


改了一下题目,现在如何?跟内存管理还是有些关系的,主要是指针

依旧木有看出有啥关系。。。。。
0 请登录后投票
   发表时间:2009-12-11  
mikeandmore 写道
lasombra 写道
Arath 写道
我觉得这个应该改为指针使用更好,并不涉及什么内存管理.


改了一下题目,现在如何?跟内存管理还是有些关系的,主要是指针

依旧木有看出有啥关系。。。。。


呵呵,行,那改成这样,没意见了吧
0 请登录后投票
   发表时间:2009-12-11  
为啥要给新手贴呢?
这不挺好么?
难道JE上的C高手比菜鸟还多?
没且没事喜欢给人家新手贴啊?
0 请登录后投票
   发表时间:2009-12-11  
lz 代码编译过?
struct node* lchild, rchild;
这句明显有问题...
0 请登录后投票
   发表时间:2009-12-11  
lasombra 写道
今天来讨论一下C中的内存管理。


  stu1->name = (char*)malloc(sizeof(char));/*3.结构体指针的成员指针同样需要初始化*/

  strcpy(stu1->name,"Lucy");


我寒,这是什么用法,不会越界吗
0 请登录后投票
   发表时间:2009-12-12  
CharlesCui 写道
为啥要给新手贴呢?
这不挺好么?
难道JE上的C高手比菜鸟还多?
没且没事喜欢给人家新手贴啊?

因为这贴的确是新手贴。。。。。
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics