动态内存

动态内存由程序员自己申请和释放,不由编译器决定。使用动态内存可以实现静态内存无法的功能和场景。

动态内存申请主要有三种方式:(此三种方式都是从进程堆中申请内存)

1.malloc() 函数用来动态地分配内存空间,其原型为:
void* malloc (size_t size);
参数说明:size 为需要分配的内存空间的大小,以字节(Byte)计。
函数说明:malloc() 在堆区分配一块指定大小的内存空间,用来存放数据。这块内存空间在函数执行完成后不会被初始化,它们的值是未知的。
返回值:分配成功返回指向该内存的地址,失败则返回 NULL。
由于申请内存空间时可能有也可能没有,所以需要自行判断是否申请成功,再进行后续操作。
如果 size 的值为 0,那么返回值会因标准库实现的不同而不同,可能是 NULL,也可能不是,但返回的指针不应该再次被引用。

2.calloc() 函数用来动态地分配内存空间并初始化为 0,其原型为:
void* calloc (size_t num, size_t size);
calloc() 在内存中动态地分配 num 个长度为 size 的连续空间,并将每一个字节都初始化为 0。所以它的结果是分配了 num*size 个字节长度的内存空间,并且每个字节的值都是0。
返回值:分配成功返回指向该内存的地址,失败则返回 NULL。
如果 size 的值为 0,那么返回值会因标准库实现的不同而不同,可能是 NULL,也可能不是,但返回的指针不应该再次被引用。
注意:函数的返回值类型是 void *,void 并不是说没有返回值或者返回空指针,而是返回的指针类型未知。所以在使用 calloc() 时通常需要进行强制类型转换,将 void 指针转换成我们希望的类型,比如char*等

3. realloc用于调整之前分配内存空间的大小,并返回新的内存空间的地址,其原型为:

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

参数说明:ptr为之前malloc,calloc或realloc之前的内存指针,size为新的内存大小

返回值:新内存地址的指针

关于realloc的使用需要注意的地方可以参考:

http://c.biancheng.net/cpp/html/2536.html

动态内存释放:

free() 函数用来释放动态分配的内存空间,其原型为:
void free (void* ptr);
free() 可以释放由malloc(),calloc(),realloc()分配的内存空间,以便其他程序再次使用。
参数说明:ptr 为将要释放的内存空间的地址。
free() 只能释放动态分配的内存空间,并不能释放任意的内存

例子1:

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


char*  upcase(char *oldString);

int  main(void)
{
    char* str1;
    str1=upcase("justTest");
    printf("%s 
",str1);
    free(str1);
    return 0;
}


char*  upcase(char *oldString){
    int counter;
    char *newString;
    if(!(newString = malloc(strlen(oldString)+1))){
        printf("ERROR ALLOCATING MEMORY
");
        exit(255);
    }
    printf("%s 
",newString);
    printf("%d 
",newString);
    strcpy(newString,oldString);
    for(counter=0;counter < strlen(newString);counter++){
        if(newString[counter]>=97 && newString[counter] <=122){
            newString[counter] -=32;
        }
    }
    return newString;
} 

运行结果:

66560
JUSTTEST

上面的例子在静态内存例子基础上做了简单的修改,对于char*通过动态内存的方式获取内存(说明通过这种方式实例化的char*和char[]一样,地址可读可写,因此strcpy没有出现段错误)。因为此内存是动态申请,因此当局部函数执行完毕后,此变量对应的内存不会被回收,可以将此内存通过指针的方式传给主函数。

另外还有一个动态申请内存的函数:void* alloca(size_t size)

此函数使用较少,且此函数是从栈上申请内存,内存会自动被回收,不需要自动回收。此函数移植性很差。

原文地址:https://www.cnblogs.com/jason207489550/p/6663562.html