结构体中动态内存的管理(malloc和free)
strcpy(pstu-> pstu-> /*创建一块内存空间,并让pstu-> pstu-> strcpy(pstu-> pstu-> 32 pstu-> 35 strcpy(pstu-> (gdb) p pstu->name ----pstu-> 36 pstu-> (gdb) p pstu-> $9 = 0x804a030 "Jimy" ----pstu-> int num = MINOR(inode-> if(num > filp-> 地址就是0x0,而在Linux中的进程虚拟存储器映射中地址0x0并没有映射,因此会出现错误。因此结构体中的指针变量一定要指向一块具体的存储空间之后才能进行相应的操作。同时其他的指针也必须指向相应的地址以后再操作。 但是分配完地址后还需要在相应操作结束后释放分配的存储器,不然会造成浪费,以及内存的泄漏。这也是很多程序员忘记完成的工作。 内存的释放采用free函数即可,free函数是将分配的这块内存与指针(malloc返回的指针)之间的所有关系斩断,指针变量P中存储的地址(这块内存的起始地址)值也没有发生变化,同时存储器中存储的内容也并没有发生改变,改变的只是指针对这块内存地址的所有权问题。但是该起始地址所在内存中的数据内容已经没法使用了,即时采用其他的指针也不能访问。如果下一次调用malloc函数可能会在刚才释放的区域创建一个内存空间,由于释放以后的存储空间的内容并没有改变(我是参考书上的,但我认为free后存储器中的内容是发生变化的,后面的调试可以说明这个问题,只是不知道发生什么变化,我也只是猜测,但是不要访问这个存储空间的内容是最安全的),这样可能会影响后面的结果,因此需要对创建的内存空间进行清零操作(防止前面的操作影响后面),这通常采用memset函数实现,具体参看memset函数。还有指针变量P中存储的地址值并没有改变,由于指针P没有对这个地址的访问权限,程序中对P的引用都可能导致错误的产生,造成野指针,因此最后还需要将指针P指向NULL,避免野指针的产生。当然也需要对创建是否成功需要检测,但这里我暂时不考虑这些错误的处理。 #include #include #include struct student { char *name; int score; }stu,*pstu; int main() { /*为name分配指向的一段内存空间*/ stu.name = (char *)malloc(20*sizeof(char)); memset(stu.name,0,20*sizeof(char)); strcpy(stu.name,"Jimy"); stu.score = 99; /*为pstu分配指向的一段内存空间*/ pstu = (struct student *)malloc(sizeof(struct student)); memset(pstu,0,sizeof(struct student)); /*为name分配指向的一段内存空间*/ pstu->name = (char *)malloc(20*sizeof(char)); memset(pstu->name,0,20*sizeof(char)); strcpy(pstu->name,"Jimy"); pstu->score = 99; /*采用另外的指针访问分配的存储空间,测试内存中内容是否改变*/ char *p = stu.name; char *p1 = (char *)0x804a008;//具体的地址值 char *ppstu = pstu->name; char *pp = (char *)0x804a030;//具体的地址值 /*释放的顺序要注意,pstu->name必须在pstu释放之前释放, *如果pstu先释放,那么pstu->name就不能正确的访问。 */ free(pstu->name); free(stu.name); free(pstu); /*为了防止野指针产生*/ pstu->name = NULL; stu.name = NULL; pstu = NULL; p = NULL; ppstu = NULL; return 0; } 下面的全部是调试结果,根据调试结果说明问题: (gdb) r Starting program: /home/gong/program/cprogram/TestStructPoint Breakpoint 1, main () at TestStructPoint.c:14 14 stu.name = (char *)malloc(20*sizeof(char)); Missing separate debuginfos, use: debuginfo-install glibc-2.12.90-17.i686 (gdb) p stu $1 = {name = 0x0, score = 0} (gdb) p stu.name $2 = 0x0 (gdb) c Continuing. Breakpoint 2, main () at TestStructPoint.c:17 17 strcpy(stu.name,"Jimy"); (gdb) p stu.name $3 = 0x804a008 "" (gdb) c Continuing. Breakpoint 3, main () at TestStructPoint.c:21 21 pstu = (struct student *)malloc(sizeof(struct student)); (gdb) p stu.name $4 = 0x804a008 "Jimy" (gdb) p stu $5 = {name = 0x804a008 "Jimy", score = 99} (gdb) p pstu $6 = (struct student *) 0x0 (gdb) c Continuing. Breakpoint 4, main () at TestStructPoint.c:24 24 pstu->name = (char *)malloc(20*sizeof(char)); (gdb) p pstu $7 = (struct student *) 0x804a020 (gdb) p pstu->name $8 = 0x0 (gdb) c Continuing. Breakpoint 5, main () at TestStructPoint.c:27 27 strcpy(pstu->name,"Jimy"); (gdb) p pstu->name $9 = 0x804a030 "" (gdb) c Continuing. Breakpoint
结构体动态内存mallocfre 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)