动态内存分配

来源:互联网 发布:n2ping for mac 编辑:程序博客网 时间:2024/06/07 14:34

1.为什么使用动态内存分配


 答:为解决未知长度数组的相关问题


2.malloc 和 free

void *malloc(size_t size); //分配动态内存void free(void *pointer);  //释放动态内存

 malloc:参数 size:需要分配的内存字节数

                 若成功,返回一个指向被分配的内存块(分配的是一个连续的内存,且未初始化)起始位置的指针

                  若失败,返回 NULL 指针

free: 参数要么是 NULL(无任何效果),要么是 malloc,calloc 或 realloc 返回的值。


3.calloc 和 realloc


void *calloc(size_t num_elements, size_t element_size);void *realloc(void *ptr, size_t new_size);

calloc:也用于分配内存,与 malloc 的区别是其在返回指向内存的指针之前它初始化为0

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

realloc:用于修改一个原先已经分配的内存块的大小

                扩大:原内容保留,新增内容放到原内存后面,并且未初始化

                缩小:内存块尾去除,剩余 部分保留

                若无法改变内存块大小,分配另一块正确大小的新内存,复制原内存到此内存块上。因此,在使用 realloc

之后,不能再使用旧内存指针,而应改用返回的新指针。

                如果重新分配成功则返回指向被分配内存的指针,否则返回空指针NULL。

                若第一个参数为 NULL,则与 malloc等效


4.使用动态内存分配

int *pi;...pi = malloc(100);if (pi == NULL){    printf("Out of memory!\n");    exit(1);}

如果分配成功,这块内存被当作25个整型元素的数组(设整形为4个字节),因为 pi 是一个指向整型的指针

如果目标就是获得足够存储25个整数的内存,有更好的可移植的技巧:

pi = malloc(25 * sizeof(int));

如何使用这块内存:可以使用间接访问和指针运算来访问数组的不同整数位置,和一般指针使用相同。


5.常见动态内存错误


错误包括对 NULL 指针进行解引用操作,对分配的内存进行操作时越过边界,释放并非动态分配的内存,试图释放一块动态分配的内存的一部分

以及一块动态内存被释放之后被继续使用。


内存泄漏:分配内存但在使用完毕后不释放将引起内存泄漏


6.内存分配实例

a. 读取一列数据,并按升序排列他们并打印

#include<stdlib.h>#include<stdio.h>int compare_integers(void const *a, void const *b)//指定排序的顺序函数{    register int const *pa = a;    register int const *pb = b;    return *pa > *pb ? 1 : *pa < *pb ? -1 : 0;}int main(){    int *array;    int n_values;    int i;    printf("How many value are there?");    if (scanf("%d", &n_values) != 1 || n_values <= 0)    {        printf("Illegal number of values.\n");        exit(EXIT_FAILURE);    }    array = malloc(n_values * sizeof(int));//分配内存    if (array == NULL)    {        printf("Can't get memory for that many values.\n");        exit(EXIT_FAILURE);    }    for (i = 0; i < n_values; i++)//读取数值    {        printf("?");        if (scanf("%d", array + i) != 1)        {            printf("Error reading value #%d\n", i);            free(array);            exit(EXIT_FAILURE);        }    }    qsort(array, n_values, sizeof(int), compare_integers);//排序(库函数)    for (i = 0; i < n_values; i++)        printf("%d\n", array[i]);    free(array);    return EXIT_SUCCESS;}

运行:

用于保存这个列表的内存是动态分配的,这样就不必担心不知道用户希望对多少个值进行排序。他实际分配的内存就是实际需要的内存,不会造成浪费。

b. 复制字符串

#include<stdlib.h>#include<stdio.h>char * strdup(char const *string){    char *new_string;    new_string = malloc(strlen(string) + 1);     if (new_string != NULL)        strcpy(new_string, string);    return new_string;}

strlen 不包含结束符,而 strcpy 是连同结束符 一起复制,所以这里要分配 比字符串长度多一个字节的内存,以便存储字符串结尾的NUL字节。


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 5岁宝宝严重挑食怎么办 孩子吃菜口味重怎么办? 孩子挑食不吃菜不吃肉怎么办 微信新的朋友回复频繁怎么办 忘了闺蜜生日怎么办 把闺蜜生日忘了怎么办 忘了闺蜜的生日怎么办 一岁宝宝不吃菜怎么办 幼儿园教案虫子爬进耳朵怎么办 鼻子出血怎么办幼儿说课 英语记不住发音不准怎么办 幼儿园孩子拼音记不住怎么办 孩子总是记不住东西怎么办 走丢了怎么办小班教案 走丢了怎么办小班社会 数学加减个十分不清怎么办 孩子b和d分不清怎么办 小孩b和d分不清怎么办 高一的数学不会怎么办 农村小孩到市里上学怎么办 和外国人打官司输了怎么办 碰见爱说你的领导怎么办 小孩脾气爆一句话就生气怎么办 小孩眼睛哭肿了怎么办 大人吵架吓到宝宝了怎么办 小孩晚上睡觉不踏实怎么办 二宝美籍大宝怎么办 小孩一洗澡就哭怎么办 孩子去外地上学学籍怎么办 非婚生子父亲想要孩子怎么办 非婚生子孩子父亲找不到了怎么办 3岁半宝宝认字怎么办 上课注意力不集中老是发呆怎么办 海绵宝宝吃了会怎么办 宝宝误吞李子核怎么办 24个月宝宝不愿意说话怎么办 孩子凉着肚子吐怎么办 教宝宝说话不会说怎么办 2岁宝宝语言退化怎么办 两周宝宝嗓子哑怎么办 幼儿园孩子上课爱说话老师怎么办