结构体中动态内存的管理(malloc和free)
#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 6, main () at TestStructPoint.c:31
31 char *p = stu.name;
(gdb) p pstu->name
$10 = 0x804a030 "Jimy"
(gdb) p *pstu
$11 = {name = 0x804a030 "Jimy", score = 99}
(gdb) p p
$12 = 0x854ff4 "|M205"
(gdb) c
Continuing.
Breakpoint 7, main () at TestStructPoint.c:32
32 char *p1 = (char *)0x804a008;//具体的地址值
(gdb) p p1
$13 = 0x855ca0 ""
(gdb) c
Continuing.
Breakpoint 8, main () at TestStructPoint.c:33
33 char *ppstu = pstu->name;
(gdb) p p1
$14 = 0x804a008 "Jimy"
(gdb) p ppstu
$15 = 0x855ca0 ""
(gdb) c
Continuing.
Breakpoint 9, main () at TestStructPoint.c:34
34 char *pp = (char *)0x804a030;//具体的地址值
(gdb) p ppstu
$16 = 0x804a030 "Jimy"
(gdb) p pp
$17 = 0x804826a "__libc_start_main"
(gdb) c
Continuing.
Breakpoint 10, main () at TestStructPoint.c:37
37 free(pstu->name);
(gdb) p pp
$18 = 0x804a030 "Jimy"
(gdb) p pstu->name
$19 = 0x804a030 "Jimy"
(gdb) c
Continuing.
Breakpoint 11, main () at TestStructPoint.c:38
38 free(stu.name);
(gdb) p pstu->name
$20 = 0x804a030 ""
(gdb) c
Continuing.
Breakpoint 12, main () at TestStructPoint.c:39
39 free(pstu);
(gdb) p stu.name
$21 = 0x804a008 "(240 04"
(gdb) p pstu
$22 = (struct student *) 0x804a020
(gdb) p *pstu
$23 = {name = 0x804a030 "", score = 99}
(gdb) c
Continuing.
Breakpoint 13, main () at TestStructPoint.c:41
41 pstu->name = NULL;
(gdb) p *pstu
$24 = {name = 0x0, score = 99}
(gdb) p pstu->name
$25 = 0x0
(gdb) c
Continuing.
Breakpoint 14, main () at TestStructPoint.c:47
47 return 0;
(gdb) p p1
$26 = 0x804a008 "(240 04"
(gdb) p pp
$27 = 0x804a030 ""
(gdb) p pstu
$28 = (struct student *) 0x0
(gdb) p pstu->name
Cannot access memory at address 0x0
(gdb)
具体的调试过程说明了其中很多的问题,根据其中的结果可以知道,free结束以后指针变量P(malloc返回)中存储的地址值并没有改变,但是通过该地值已经不能访问之前的分配的存储空间。我采用其他的指针(直接赋值地址以及指针赋值)访问得到的结果也不是正确的值,虽然这不能说明地址中的数据改变了,但说明对释放以后的存储空间再通过其他方法访问不会得到正确的值,但是内存空间中存在值,并不一定是0,因此每一次malloc都清零是必要的。防止野指针也是非常必要的,减少程序错误的概率。
关键词:
结构体动态内存mallocfre
评论