结构体中动态内存的管理(malloc和free)
其中最大的问题是:结构体中指针变量没有指向一块合法的内存空间,就对指针参数进行操作,这也是很多C语言程序员经常犯的错误。
简单的实例如下:
struct student
{
char *name;
int score;
}stu,*pstu;
int main()
{
strcpy(stu.name,"Jimy");
stu.score = 99;
strcpy(pstu->name,"Jimy");
pstu->score = 99;
}
这种代码是新手经常犯的错误,其中的主要错误是指针变量没有指向一块内存空间,其中包括ptest没有指向一块内存空间,同时结构体中的指针变量name也没有指向一块内存空间。
这种代码一般都会编译通过,但是运行过程中会发生新手编程经常出现的段错误Segmentation fault (core dumped),我通过gdb对程序进行调试发现了存在的一些问题。其中stu.name中的内容是0x0,也就是地址0x0。这样我就知道了0x0为什么会发生段错误了,因为在Linux中进程都有一个独立的虚拟存储空间4G,但是其中在最底部的0x0是没有映射的,具体的参看进程的存储器映射关系。0x0并没有映射,这样发生段错误也就不奇怪了。
也就是说指针变量里存储的地址值并不是一个我们需要的值,为了指向一块内存空间,因此需要采用malloc分配一块内存空间。
改写上面的代码实现内存的分配。
int main()
{
/*创建一块内存空间,并让stu.name指向这块内存空间*/
stu.name = (char *)malloc(20*sizeof(char));
/*实现字符串的复制过程*/
strcpy(stu.name,"Jimy");
stu.score = 99;
/*创建一块内存空间,并让pstu指向这块内存空间*/
pstu = (struct student *)malloc(sizeof(struct student));
/*创建一块内存空间,并让pstu->name指向这块内存空间*/
pstu->name = (char *)malloc(20*sizeof(char));
/*实现字符串的复制过程*/
strcpy(pstu->name,"Jimy");
pstu->score = 99;
return 0;
}
这样补充以后的代码就为指针变量添加了指向的对象,由于是采用malloc动态申请的存储空间,那么这段存储空间是分配在堆中,而不是在栈中,如果是在被调用函数中申请内存空间,那么在函数返回后该内存空间并不会释放。
Breakpoint 1, main () at TestStructPoint.c:21
21 stu.name = (char *)malloc(20*sizeof(char));
Missing separate debuginfos, use: debuginfo-install glibc-2.12.90-17.i686
(gdb) p stu ----stu中的内容
$1 = {name = 0x0, score = 0}
(gdb) p stu.name ----stu.name其中的内容是0x0,也就是指向0x0
$2 = 0x0
(gdb) c
Continuing.
Breakpoint 2, main () at TestStructPoint.c:25
25 strcpy(stu.name,"Jimy");
(gdb) p stu.name -----stu.name其中的内容不再是0x0,而是一个地址值,该地值中的内容为空
$3 = 0x804a008 ""
(gdb) c
Continuing.
Breakpoint 3, main () at TestStructPoint.c:26
26 stu.score = 99;
(gdb) p stu.name -----stu.name中存储的地址的内容发生了变化。
$4 = 0x804a008 "Jimy"
(gdb) c
Continuing.
Breakpoint 4, main () at TestStructPoint.c:29
29 pstu = (struct student *)malloc(sizeof(struct student));
(gdb) p pstu ----pstu指向的地址也是0x0
$5 = (struct student *) 0x0
(gdb) c
Continuing.
Breakpoint 5, main () at TestStructPoint.c:32
32 pstu->name = (char *)malloc(20*sizeof(char));
(gdb) p pstu ----pstu指向的内存地址发生了改变,不再是0x0
$6 = (struct student *) 0x804a020
(gdb) c
Continuing.
Breakpoint 6, main () at TestStructPoint.c:35
35 strcpy(pstu->name,"Jimy");
(gdb) p pstu
$7 = (struct student *) 0x804a020
(gdb) p pstu->name ----pstu->name中的地址也不再是0x0,而是一个非零的地址值
$8 = 0x804a030 ""
(gdb) c
Continuing.
Breakpoint 7, main () at TestStructPoint.c:36
36 pstu->score = 99;
(gdb) p pstu->name
$9 = 0x804a030 "Jimy" ----pstu->name指向地址中的内容发生改变
(gdb) c
Continuing.
Program exited normally.
根据上面的调试可以知道,指针变量在定义过程中没有初始化为NULL,则指针变量指向的
结构体动态内存mallocfre 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)