数据结构-c语言内的内存分配

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构-c语言内的内存分配相关的知识,希望对你有一定的参考价值。

常用到的数据存储区:

在C语言中,根据数据在内存中存在的时间(生存期)不同,将内存空间分为三个区:

1.程序区:用于存储程序的代码,即程序的二进制代码;

2.静态存储区:用于存储全局变量和静态变量,这些变量的空间在程序编译时就已经分配好了;

3.动态存储区:用于在程序执行时分配的内存,又分为:堆区(heap)和堆栈区(stack)两种。

                 堆区:用于动态内存分配,程序运行时由内存分配函数在堆上分配内存。在C语言中,只要使用指针才能动态的分配内存。

                 堆栈区:在函数执行时,函数内部的局部变量和函数参数的存储单元的内存区域,函数运行结束时,这些内存区域会自动释放。在数据结构-栈的应用时提到栈用于实现函数调用,系统需要为函数调用创建变量存储区,这里的存储区就是从堆栈区申请,堆栈区的栈就是表示栈使用。

 

指针实例:

 1 #include <stdio.h>
 2 
 3 int main(void)
 4 {
 5     int *num = NULL;
 6     int *x, y[] = {12, 22,32}, z = 100;
 7 
 8     //下面演示,指针既可充当变量、也可充当数组
 9     x=&z;      //整型变量的地址赋给x
10     printf("*x=%d, x[0]=%d\\n", *x, x[0]);//100,100 
    &z表示将z的地址付给x
    *x表示去当前指针的内容
11 12 x = y; //数组的地址赋给x 13 printf("*x=%d, x[ 0]=%d, x[ 1]=%d, x[2]=%d\\n", *x, x[0], x[1], x[2]);//12 12 22 32
    将数组的首地址赋给x
14 15 x = y + 1; //数组的第二位地址赋给x 16 printf("*x=%d, x[-1]=%d, x[ 0]=%d, x[1]=%d\\n", *x, x[-1], x[0], x[1]);//22 12 22 32 17 18 x = y + 2; //数组的第三位地址赋给x 19 printf("*x=%d, x[-2]=%d, x[-1]=%d, x[0]=%d\\n", *x, x[-2], x[-1], x[0]);//32 12 22 32 20 21 return 0; 22 }

 

内存泄漏主要有以下几种情况:

  1. 内存分配未成功,却使用了它。
  2. 内存分配虽然成功,但是尚未初始化就引用它。
  3. 内存分配成功并且已经初始化,但操作越过了内存的边界。
  4. 忘记了释放内存,造成内存泄露。
  5. 释放了内存却继续使用它。

 

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 int main(void)
 5 {
 6     int *p, i;
 7 
 8     p = (int *)malloc(6 * sizeof(int)) ;
 9     if (p == NULL) {    //判断是否为空
10         printf("内存分配出错!");
11         exit(1);
12     }
13 
14     for (i=0; i<6; i++) {
15         p++;
16         *p = i;
17         printf("%2d", *p);
18     }
19     printf("\\n");
20 
21     free(p);    //这句运行时出错
22 
23     return 0;
24 }

 

自己觉得这个程序指针使用方式可以换成以下这种:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int *p, i;

    p = (int *)malloc(6 * sizeof(int)) ;
    if (p == NULL) {    //判断是否为空
        printf("内存分配出错!");
        exit(1);
    }

    for (i=0; i<6; i++) {      
        p = &i;
        printf("%2d", *p);
        p++;
    }
    printf("\\n");

    free(p);    //运行这句是争取的

    return 0;
}

 

内存释放

在函数内使用的指针动态分配了内存,用完后不释放。其理由是:函数运行结束后,函数内的所有变量全部消亡。这是错误的。动态分配的内存是在“堆”里定义,这个堆是系统使用的自由存储空间,只有等程序结束后才会销毁,并不随函数结束而消亡。

动态分配了内存的指针,用完后直接设置为NULL。其理由是:已经为NULL了,这就释放了。这也是错误的。指针可以任意赋值,而内存并没有释放;相反,内存释放后,指针也并不为NULL。

指针置为NULL,是表示指针指向空地址,但是指针依然占用内存,没有释放掉,可能会导致内存泄漏。

 

 

参考链接:

http://www.cnblogs.com/jiajinghai/archive/2011/11/09/2243709.html

http://www.quanxue.cn/jc_clanguage/CLang/Clang13.html

以上是关于数据结构-c语言内的内存分配的主要内容,如果未能解决你的问题,请参考以下文章

[转]深入C语言内存区域分配(进程的各个段)详解

C语言 动态内存分配机制(堆区) int*p=malloc(5*sizeof)

C语言中一个分号的奇迹(预处理指针结构体内存分配)——一段暗藏玄机的代码

C 语言结构体 ( 结构体中嵌套一级指针 | 分配内存时先 为结构体分配内存 然后再为指针分配内存 | 释放内存时先释放 指针成员内存 然后再释放结构头内存 )

C 语言结构体 ( 结构体中嵌套二级指针 | 为 结构体内的二级指针成员 分配内存 | 释放 结构体内的二级指针成员 内存 )

c语言数组在内存中是怎么分配的?