Linux/Unix C编程2

C语言中的malloc函数:

头文件:stdlib.h

malloc以字节做参数,返回内存的首地址,如果出错返回NULL;

分配内存的区间:堆区(注1)

free用来回收malloc分配的内存,参数是malloc返回的首地址。

通常用void *接收malloc返回的首地址。void *可以进行加减运算,以一个字节作为偏移单位,但这种运算没有什么实际意义。

malloc分配的内存,如果存储字符串,用strcpy进行赋值。用=赋值,会导致用free回收内存时,出现段错误。(char数组也用进行赋值)。
如,以下这种写法在编译的时候不会报错,但在运行的时候会出现段错误。可以用strcpy(s,"abcd");进行赋值,就不会出现这种现象。
    #include<stdio.h>
    #include<stdlib.h>
    
    int main(){
    char *s=(char *)malloc(5);
    s="abcd";
    free(s);
    return 0;
    }
    至于原因"abcd"字符串会放在字符数组中,指针变量s存放的时地址,s="abcd";相当与将abcd只读区的地址赋值给s。而free作用的区域是堆区,所以不能对s进行内存回收。我们需要将free(s)注释掉,运行就可以通过。但这样就造成一个问题内存的泄露(注2);

注1:
    编程和内存划分为如下:
    A.静态数据区:内存在程序启动的时候才被分配,而且可能直到程序开始执行的时候才被初始化,如函数中的静态变量就是在第一次执行到定义该变量的代码时才被初始化。所分配的内存在程序的整个运行期间都存在,如全局变量,static变量等。

    注:初始化的全局变量和静态变量在同一块区域,未初始化的全局变量与静态变量在相邻的另一块区域,同时未被初始化的对象存储区也可以通过void*来访问和操纵,程序结束后由系统自行释放。

    B.代码区:存放函数体的二进制代码;

    C.栈区:存放自动变量。在函数执行的时,函数的局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元由编译器自动释放,超出其作用域的操作没有定义。
栈内存分配运算内置处于处理器的指令集中,效率很高,但分配的内存容量有限。栈存放函数的参数值,局部变量的值等。

    D.堆区(自由存储区):在运行的时候调用程序(如C中的malloc或C++的new)分配内存,可以在任何时候决定分配内存及分配的大小。用户自己负责何时释放内存(如用free和delete)。堆中所有东西时匿名的,这样不能按名字访问,而只能通过指针访问。
    
    函数指针指向Code区,是程序运行的指令代码,数据指针指向Data,Heap,Stack区,是程序依赖运行的各种数据。

    在文件作用域声明inline函数默认为static存储类型,const常量默认为static存储,如果加上extern,则为外部存储。

转自:http://sunxiasheng.blog.163.com/blog/static/39908031200861910272378/

注2:内存泄漏
    一般的内存泄漏是指堆内存的泄漏。堆内存是从程序内分配的一块内存,大小任意的(内存的大小的可以在程序运行期决定),使用完之后,必须显式释放内存。应用程序一般使用malloc,calloc,realloc,new等函数从堆中分配内存,使用完之后程序必须调用free或delete释放该内存块,否则这块内存就不能再使用,我们就说这块内存泄漏了

(转自百度知道 C语言中什么叫内存泄漏,回答者:夏雨的忧伤)

posted @ 2013-06-24 21:47  SpringJiang  阅读(214)  评论(0编辑  收藏  举报