今天来讨论一下C中的内存管理。 记得上周在饭桌上和同事讨论C语言的崛起时,讲到了内存管理方面 我说所有指针使用前都必须初始化,结构体中的成员指针也是一样 有人反驳说,不是吧,以前做二叉树算法时,他的左右孩子指针使用时难道有初始化吗 那时我不知怎么的想不出理由,虽然我还是坚信要初始化的 过了几天这位同事说他试了一下,结构体中的成员指针不经过初始化是可以用(左子树和右子树指针) 那时在忙着整理文档,没在意 今天抽空调了一下,结论是,还是需要初始化的。 而且,不写代码你是不知道原因的(也许是对着电脑久了IQ和记性严重下跌吧) 测试代码如下
C代码 #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; } #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来分配内存,而是将另一个指针的值赋给它 顿时觉得挺无语的,确实,看了很多大学里的教材,对于二叉树的遍历等算法定义的结构体无非是以下形式
C代码 struct node{ int data; struct node* lchild, rchild; }; struct node{ int data; struct node* lchild, rchild; };使用时都直接的
C代码 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; 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哥! /*附加:仍旧是指针*/
C代码 stu1 = (struct student*)malloc(sizeof(struct student));/*2.结构体指针需要初始化*/ stu1 = (struct student*)malloc(sizeof(struct student));/*2.结构体指针需要初始化*/这一句可能会有人把sizeof里边也填成struct student* 可以理解这样的行为,因为stu本来就是struct student*,可是这样子你就没有为结构体分配足够的内存,使用中会因为内存错误同样报错的。 当然,仅仅为结构体指针分配内存还不够,结构体成员指针仍然需要分配内存,如下
C代码 stu1->name = (char*)malloc(sizeof(char));