申请动态分配内存 malloc()
stdlib.h 中定义函数 void* malloc(size_t size)
向系统申请大小为 size 的内存空间
返回结果是 void*,使用时转换成需要的指针类型
如果申请失败,返回 NULL
向系统申请一块 n*4 字节的空间
(int*)malloc(n*sizeof(int))
#include
#include
int main(){
int n;
scanf("%d",&n);
// 等同于 int arr[n];
int* arr = malloc(n*sizeof(int));
for(int i=0;i<n;++i){
scanf("%d",arr+i);
}
for(int i=0;i<n;++i){
printf("%d ",arr[i]);
}
printf("\n");
free(arr); // 释放指针
arr = NULL;
}
结果为:
5
1 2 3 4 5
1 2 3 4 5
释放动态分配内存 free()
注意 free() 的问题:
已经释放了,但每清空,就会形成野指针,野指针如果再次使用,就会报错
另外还有一个函数
calloc(n,sizeof(int))
格式与 malloc() 不同,但作用和 malloc() 相同
函数 | 作用 |
---|---|
malloc() | 分配内存块,不初始化 |
calloc() | 分配内存块,初始化为0 |
realloc() | 调整先前分配的内存块大小 |
free() | 释放分配内存块 |
从终端输入未知个数的数字,用ctrl+d结束,并输出所有输入的数
#include
#include
int main(){
int* arr = NULL;
int count = 0;
for(;;){
int m;
int res = scanf("%d",&m);
// 输入结束会返回EOF,为Ctrl+z 或者Ctrl+d
if(EOF == res) break;
/*
if(count == 0){
arr = calloc(1,sizeof(int));
}else{
arr = realloc(arr,sizeof(int)*(count+1));
}
*/
// 当 arr == NULL 时,realloc() 相当于 malloc()
arr = realloc(arr,sizeof(int)*(count+1));
arr[count] = m;
++count;
}
for(int i=0;i<count;++i){
printf("%d ",arr[i]);
}
printf("\n");
free(arr);
arr = NULL;
}
结果为:
1 2 3 4 5 6
7 6 5 4 3 2
1 2 3
1 2 3 4 5 6 7 6 5 4 3 2 1 2 3
函数 | 含义 |
---|---|
memset() | 填充内存 |
memcpy() | 内存拷贝 |
memmove() | 内存移动 |
memcmp() | 内存比较 |
memchr() | 查找内存中第一个出现指定字符的位置 |
例如: memcpy(拷给谁,从谁那拷,拷的字节数);
给数组赋值,比较数组,移动数组:
#include
#include
int main(){
int arr1[] = {1,2,3,4,5};
int arr2[5];
/*
for(int i=0;i<5;++i){
arr2[i] = arr1[i];
}
*/
// 把arr1的值拷贝到arr2中
memcpy(arr2,arr1,sizeof(arr1));
for(int i=0;i<5;++i){
printf("%d ",arr2[i]);
}
printf("\n");
// arr1和arr2做比较
arr2[3] = 9;
if(memcmp(arr1,arr2,sizeof(arr1)) == 0){
printf("相等\n");
}else{
printf("不相等\n");
}
// arr1成员向前移一个
memmove(arr1,arr1+1,4*sizeof(int));
for(int i=0;i<5;++i){
printf("%d ",arr1[i]);
}
printf("\n");
}
结果为:
1 2 3 4 5
不相等
2 3 4 5 5
传入一维指针地址可以取出函数内部申请的单个变量的动态内存
理解二维指针作为函数参数:
#include
#include
void Func(int** pp){
*pp = malloc(sizeof(int));
**pp = 100;
printf("%p\n",*pp);
printf("%d\n",**pp);
}
int main(){
int* p = NULL;
Func(&p);
printf("%p\n",p);
printf("%d\n",*p);
free(p);
p = NULL;
}
结果为:
0x9a42a0
100
0x9a42a0
100
首先,malloc() 需要把内存传给一个指针,其次,无返回值函数传参本身就需要通过指针保证修改的解引用是一个东西,所以,要用到二维指针
有返回参数的情况:
#include
#include
int* Func2(){
int* p = malloc(sizeof(int));
*p = 200;
printf("%p\n",p);
printf("%d\n",*p);
return p;
}
int main(){
int* p = NULL;
p = Func2();
printf("%p\n",p);
printf("%d\n",*p);
free(p);
p = NULL;
}
结果为:
0x19ca2a0
200
0x19ca2a0
200
传入一维指针地址也可以取出函数内部申请的一个数组的动态内存
函数传参方式打印函数中数组后:
#include
#include
void Func(int** pp){
*pp = malloc(sizeof(int)*10);
for(int i=0;i<10;++i){
(*pp)[i] = i;
}
}
int main(){
int* p = NULL;
Func(&p);
for(int i=0;i<10;++i){
printf("%d ",p[i]);
}
printf("\n");
free(p);
p = NULL;
}
结果为:
0 1 2 3 4 5 6 7 8 9
可以把二维数组 arr[n][m]
想成 n 个一维数组 arr[m]
申请 n 个一维数组内存空间 malloc(m*sizeof(int));
再给这 n 个内存指针申请一个空间 malloc(n*sizeof(int*))
动态内存创建二维数组:
#include
#include
int main(){
int n,m;
scanf("%d%d",&n,&m);
int** parr = malloc(n*sizeof(int*));
for(int i=0;i<n;++i){
parr[i] = malloc(m*sizeof(int));
for(int j=0;j<m;++j){
scanf("%d",&parr[i][j]);
}
}
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
printf("%d ",parr[i][j]);
}
printf("\n");
}
for(int i=0;i<n;++i){
free(parr[i]);
parr[i] = NULL;
}
free(parr);
parr = NULL;
}
结果为:
2 3
1 2 3
4 5 6
1 2 3
4 5 6
malloc 把新建的空间给那个指针,就要用 free 释放哪个指针
练习题:
#include
void swapString(char** pa,char** pb){
char* t = *pa;
*pa = *pb;
*pb = t;
}
int main(){
char* a = "123";
char* b = "abcd";
printf("a:%s\n",a);
printf("b:%s\n",b);
swapString(&a,&b);
printf("a:%s\n",a);
printf("b:%s\n",b);
}
结果为:
a:123
b:abcd
a:abcd
b:123
#include
#include
int main(){
int n;
scanf("%d",&n);
char** res = malloc(n*sizeof(char*));
for(int i=0;i<n;++i){
res[i] = calloc(i+2,sizeof(char)); // 包括\0
for(int j=0;j<=i;++j){
res[i][j] = '*';
}
}
for(int i=0;i<n;++i){
printf("%s\n",res[i]);
}
for(int i=0;i<n;++i){
free(res[i]);
res[i] = NULL;
}
free(res);
res = NULL;
}
结果为:
4
*
**
***
****
#include
#include
#include
int main(){
int n,m;
scanf("%d%d",&n,&m);
// 生成随机数
srand(time(NULL));
// 要n~m的数
int row = rand()%(m-n)+n; // 随机行
char** table = malloc(row*sizeof(char*));
for(int i=0;i<row;++i){
int col = rand()%(m-n)+n; //随机列
table[i] = calloc(col+1,sizeof(char)); // 记得\0
for(int j=0;j<col;++j){
table[i][j] = '*';
}
}
for(int i=0;i<row;++i){
printf("%s\n",table[i]);
}
for(int i=0;i<row;++i){
free(table[i]);
table[i] = NULL;
}
free(table);
table = NULL;
}
结果为:
2 8
******
*******
**
****