C

静态存储区分配

内存分配在程序编译之前完成,且在程序的整个运行期间都存在,例如全局变量、静态变量等。

栈上分配

在函数执行时,函数内的局部变量的存储单元在栈上创建,函数执行结束时这些存储单元自动释放。

堆上分配

堆分配(又称动态内存分配)。程序在运行时用malloc或者new申请内存,程序员自己用free或者delete释放,动态内存的生存期由我们自己决定。

malloc()函数

原型:extern void *malloc(unsigned int num_bytes);

头文件:在TC2.0中可以用malloc.h或 alloc.h (注意:alloc.h 与 malloc.h 的内容是完全一致的),而在Visual C++6.0中可以用malloc.h或者stdlib.h。

功能:分配长度为num_bytes字节的内存块

返回值:如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。当内存不再使用时,应使用free()函数将内存块释放。

说明:关于该函数的原型,在旧的版本中malloc返回的是char型指针,新的ANSIC标准规定,该函数返回为void型指针,因此必要时要进行类型转换。

#include<stdio.h>
#include<malloc.h>

void out(int *p,int n)
{
    int i;
    for(i=0;i<n;i++)
    {   
        printf("%d",*(p+i));
        printf("---------------\n");
    }   

}

int main(void)
{
    printf("please input one number:");
    int n;
    scanf("%d",&n);
    //申请
    int *p = (int *)malloc(n * sizeof(int));
    //内存申请成功
    if(p != NULL){
        out(p,n);
        int i;
        for(i=0;i<n;i++){
            *(p+i)=i*i;
        }
        out(p,n);
        //释放掉堆内存
        free(p);
    }else{
        //内存申请失败
        printf("malloc is NULL!\n");
    }   
    return 0;
}

calloc函数:需要用到的头文件stdlib.h

void *colloc(size_t num_elements,size_t element_size);

功能:功能同malloc是一样的,在内存的动态存储区中分配n个长度为size的连续空间,函数返回一个指向分配起始地址的指针;如果分配不成功,返回NULL。

参数:num_elements是所需的元素的数量,element_size是每个元素的字节数

返回:同malloc函数一样

也是需要与free(p)进行对称使用

跟malloc的区别:calloc在动态分配完内存后,自动初始化该内存空间为零,而malloc不初始化,里边数据是随机的垃圾数据。

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

int main(void)
{
    printf("please input one number:");
    int n;
    scanf("%d",&n);
    int *p = (int *)calloc(n,sizeof(int));
    if(p!=NULL){
        int i;
        for(i=0;i<n;i++)
        {
            printf("%d ",*(p+i));
        }
        printf("\n");
        free(p);
    }else{
        printf("calloc error\n");
    }   
    return 0;
}

realloc函数

需要用到的头文件(stdlib.h),动态扩大缩小申请的内存

void *realloc(void *ptr,size_t new_size);

功能:在指针ptr指向的内存基础上扩大或者缩小内存

参数:ptr是指向先前通过malloc,calloc和realloc函数后分配的内存块的指针,new_size是内存块的新尺寸,可能大于或者小于原有内存尺寸;这个是追加到new_size的新的内存

realloc在C语言中也被称为动态数组;

realloc函数使用的注意点:

  1. 当扩展内存的时候,不会对添加进内存块的字节进行初始化
  2. 若不能调整内存则返回NULL,但原有内存中的数据是不会发生改变的
  3. 若第一个参数为NULL那么功能 等同与malloc函数,若第二个参数为0,那么会释放调用内存块
realloc(NULL,10*size(int)) 等同malloc(10*sizeof(int));
realloc(p,0); 等同于free
#include<stdlib.h>
#include<stdio.h>
#include<malloc.h>
void out(int *p ,int n){ 
    int i;
    for(i = 0 ;i < n; i++){
        printf("%d\n",*(p+i));
    }   
}
int main(void)
{   
    //申请4个字节的堆内存空间,未初始化
    int * p = (int *)malloc(5*sizeof(int));
    if(p == NULL) exit(1);
    *p = 1;
    *(p+1)  =2; 
    p[2] = 3;
    p[3] = 4;
    p[4] = 5;
    out(p,5);
    printf("===============\n");
    //追加申请10个字节的内存空间,追加的空间也是未进行初始化的
     p = (int *)realloc(p,10*sizeof(int));
    if(p == NULL) exit(1);
    p[6] = 6;
    *(p+6) = 7;
    *(p+7) = 8;
    *(p+8) = 9;
    *(p+9) = 10; 
    out(p,10);
    free(p);
    //free之后,将指针置为空
    p = NULL;
    return 0;
}

free函数

free之后如果还有这块内存地址的话,此时这块内存归还给了系统,(可能这块内存还处于一个空闲状态)但是还是可以对其进行操作。里面的值短暂的会保留。 free之后,申请内存的那个指针就会变成野指针(声明了,但是没有任何指向的指针),有时候会出现野指针错误; 所以尽量在操作之后:将指针置为NULL

p=NULL;

注意:申请和释放是成对的,所以程序是不能进行多次free的,否则会崩溃的

常见的内存错误

段错误

使用未分配成功的内存
避免方式:在使用内存之前检查指针是否为NULL;

引用分配成功但尚未初始化的内存
避免方式:赋予初值,即便是赋予零值也不可省略

内存分配成功并且已经初始化,但操作越过了内存的边界
避免:注意下表的使用不能超出边界

忘记释放内存,造成内存泄露
避免方式:申请内存的方式和释放内存的方式需要成双成对

释放内存之后却继续去使用这一块内存
避免方式:使用free内存之后,把指针置为NULL;

内存错误的注意点

指针消亡了,并不表示它所指向的内存会被自动释放,(在free之前,直接将指针设为NULL); 内存释放了,并不代表指针会消亡或者成了NULL指针;(在free之后,指针并没有进行NULL设置)

野指针

野指针的形成是指针变量没有被初始化,任何指针变量刚被创建的时候不会自动成为NULL指针,它的缺省值是最忌的,它会乱指一气

指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法内存

free内存块之后,需要将指针设置为NULL,如果没有设置为NULL,也会出现“野指针”,它是指向“垃圾”内存的指针;

多次free内存块,是会导致程序崩溃的



あなたのお住まいの地域で最安のブロードバンド選び

コメント:



(画像の文字列を入力して下さい)

トップ   編集 凍結 差分 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2019/12/02 (月) 12:32:57 (1628d)

yVoC[UNLIMITȂ1~] ECirŃ|C Yahoo yV LINEf[^[Ōz500~`I


z[y[W ̃NWbgJ[h COiq 萔O~ył񂫁z COsیI COze