微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 结构体中动态内存的管理(malloc和free)

结构体中动态内存的管理(malloc和free)

时间:12-01 来源:互联网 点击:
C语言中内存的管理主要是依据malloc和free实现的,其中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,则指针变量指向的

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top