7-7 动态内存分配
1. malloc
直接创建数组一般存储在函数调用栈上,而使用 malloc 分配内存从而进行存储的数据则是存放在堆区;堆区的数据与函数调用栈上的数据不同,堆区数据在函数释放后也不会释放内存,需要用 free() 主动释放
#include
#include
#define PLAYER_COUNT 10int main(){int *players = malloc(PLAYER_COUNT * sizeof(int));for (int i = 0; i < PLAYER_COUNT; ++i) {players[i] = i;}for (int i = 0; i < PLAYER_COUNT; ++i) {printf("%d ", players[i]);}free(players); // 释放内存return 0;
}
2. 函数参数应为二维指针
free() 释放后的内存块对存在其中的值无影响,还会保留在内存块中,所以在调用 malloc 时,需要对新来的内存块上的值进行初始化操作(初始化操作中的二维指针,实质上就是在函数内部修改外部的指针变量,看自己那篇18年的博客,有详解)
#include
#include #define PLAYER_COUNT 10void InitPointer(int **ptr, int length, int default_value){*ptr = malloc(length * sizeof(int));for (int i = 0; i < length; ++i) {(*ptr)[i] = default_value;}
}int main(){// 和向函数传递想要修改的参数值的情况相同,必须将变量的地址传入函数才能进行修改,此处就是指针变量的地址传入InitPointer函数,进而修改指针变量的值int *players;InitPointer(&players, PLAYER_COUNT, 2);for (int i = 0; i < PLAYER_COUNT * 2; ++i) {printf("%d ", players[i]);}free(players);return 0;
}
3. calloc
函数 calloc 与 malloc 不同,calloc 返回的内存会自动被清为 0,相当于做了一个预处理工作,不用自己做
players = calloc(PLAYER_COUNT, sizeof(int));
4. realloc
realloc 函数,对原先的内存(注意,是在原有的内存基础上进行分配的)进行重新分配并增加或减少部分内存(以旧换新的感觉),但注意,realloc 新加的内存不会做清空操作,里面的值不能确定
int *players;
InitPointer(&players, PLAYER_COUNT, 2);// 函数 realloc 的用法
players = realloc(players, 4*sizeof(int)); // 重新分配四块内存
for (int i = 0; i < PLAYER_COUNT; ++i) {printf("%d ", players[i]); // 2 2 2 2 -842150451 ... ,只能确定前四个值,后面的值无法确定,因为是在原有空间的基础上重新分配了四块内存
}printf("\n");players = realloc(players, PLAYER_COUNT * 2 * sizeof(int)); // 重新分配20块内存for (int i = 0; i < PLAYER_COUNT * 2; ++i) {printf("%d ", players[i]); // 2 2 2 2 -842150451 -842150451 -842150451 ... 后面一直都是 -842150451,这个数字是什么含义?
}free(players);
5. 分配内存之后...
内存分配可能会失败,所以在使用 malloc calloc realloc 函数后,需要判断指针是否分配到了内存
if(players){... // 指针指向的地方有内存才有意义}else{...}
6. 注意事项
常见指针使用错误:
1)忘记在使用指针完毕后释放内存
2)使用了已经释放的内存(指针指向的内存被释放,但是指针变量并没有被销毁,还是可以继续使用的,如果在 free() 后再次使用该指针变量,就是这种情况,这种指针就是野指针)
3)使用了超出边界的内存(类似数组越界)
4)改变了内存的指针,导致无法正常释放(一个指针变量指向一块内存,如果这时将指针变量的值修改,使其指向其他内存,那原有的那块内存就会无法正常释放,因为没有指针变量指向它)
动态内存使用建议:
1)避免修改指向已分配内存的指针(对应 4)
2)对于 free() 后的指针主动置为 NULL(对应 2)
3)避免将过多的指针指向动态分配的内存(一旦其中一个指针使用 free() 操作,其他指针根本不知道,其他指针就化为了野指针)
4)动态内存遵从谁分配谁释放的原则
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
