结构体指针变量与结构体成员指针变量

今天来讨论一下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));
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值