我们通常开辟空间的方式
int val =20; //大小为4个字节
char arr[10] ={0} //开辟出一块连续的空间且大小为10
但是以上的方式不能满足所有情况,有时候我们需要空间的大小在程序运行的时候才能知道,
那数组编译的方式就不能满足了,你那就可以使用动态内存
一.堆区,栈区,静态区
二.动态内存函数
1.malloc函数
头文件 #include<stdlib.h>
函数格式
void*malloc(size_t size)
2.free函数
头文件 #include<stdlib.h>
void free (void* ptr);
malloc函数和free函数使用如下
#include<string.h>
#include<stdio.h>
#include<errno.h>
#include<stdlib.h>
int main()
{
//向内存申请空间,且未初始化
int* p = (int*)malloc(20);
//判断空间是否开辟成功
if (p == NULL)
{
//判断错误的原因
//strerror函数是用来判断错误的原有
printf("%s\n", strerror(errno));
return 1;
}
//使用
int i = 0;
for (i = 0; i < 5; i++)
{
//这俩种形式等价
//*(p + i) = i + 1;
//printf("%d ", *(p + i));
//p[i] = i + 1;
//printf("%d ", p[i]);
}
//释放
free(p);
p = NULL;
return 0;
}
注意:
如果malloc函数开辟的空间太大,则会开辟失败
3.calloc函数
头文件:#include<stdio.h>
void* calloc (size_t num, size_t size);
calloc函数和free函数的使用
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
int main()
{
//开辟动态空间
int* p = (int*) calloc(10, sizeof(int));
//判断是否开辟成功
if (p == NULL)
{
printf("%s", strerror(errno));
return 1;
}
//使用
int i = 0;
//进行空间的遍历
for (i = 0; i < 10; i++)
{
printf("%d ", p[i]);
}
return 0;
//释放内存
free(p);
p = NULL;
}
程序运行
4.realloc函数
头文件:#include<stdlib.h>
格式
void* realloc (void* ptr, size_t size);
realloc函数的应用
#include<stdio.h>
#include<stdlib.h>
%include<errno.h>
int main()
{
//开辟动态空间
int* p = (int*) calloc(10, sizeof(int));
//判断是否开辟成功
if (p == NULL)
{
printf("%s", strerror(errno));
return 1;
}
//重新分配内存使其能容纳80个字节的空间,成功使用
//realloc函数后,原来由calloc函数开辟的空间会被回收
//所以不需要对p进行释放,如果释放,则会导致程序崩溃
int* pa = realloc(p, 80);
if (pa == NULL)
{
printf("%s", strerror(errno));
return 1;
}
//使用
int i = 0;
for (i = 0; i < 20; i++)
{
*(pa+i) = i + 1;
printf("%d ",*(pa+i));
}
//释放
free(pa);
pa = NULL;
}
程序运行:
realloc在调整内存空间有俩种情况
1.原有空间之后有足够大的空间
2.原有空间之后没有足够大的空间
情况1:在原来的空间直接进行扩展
情况2:没有找到足够的空间,在另一处又开辟了一个空间
三.动态内存中常见的错误
void test()
{
int *p = (int *)malloc(INT_MAX/4);
*p = 20;
free(p);
}
这段代码有什么问题呢👆
void test()
{
int i = 0;
int *p = (int *)malloc(10*sizeof(int));
if(NULL == p)
{
exit(EXIT_FAILURE);
}
for(i=0; i<=10; i++)
{
*(p+i) = i;
}
free(p);
}
这段代码有什么问题呢👆
void test()
{
int a = 10;
int *p =
free(p);//ok?
}
void test()
{
int *p = (int *)malloc(100);
p++;
free(p);
}
void test()
{
int *p = (int *)malloc(100);
free(p);
free(p);、
}
void test()
{
int *p = (int *)malloc(100);
if(NULL != p)
{
*p = 20;
}
}
int main()
{
test();
while(1);
}
四.经典的笔试题
void GetMemory(char *p)
{
p = (char *)malloc(100);
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}
请问这段代码错误出在哪👆
char *GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}
请问这段代码错误出在哪👆
void GetMemory(char **p, int num)
{
*p = (char *)malloc(num);
}
void Test(void)
{
char *str = NULL;
GetMemory(
strcpy(str, "hello");
printf(str);
}
请问这段代码错误出在哪👆
void Test(void)
{
char *str = (char *) malloc(100);
strcpy(str, "hello");
free(str);
if(str != NULL)
{
strcpy(str, "world");
printf(str);
}
}
请问这段代码错误出在哪👆
五.柔性数组
柔性数组的创建
第一种方式👇
typedef struct st_type
{
int i;
int a[0];//柔性数组成员
}type_a;
第二种方式👇
typedef struct st_type
{
int i;
int a[];//柔性数组成员
}type_a;
柔性数组的特点
1.sizeof返回的大小不包含柔性数组的大小
#include<stdio.h>
struct s
{
int i;
int a[0];//柔性数组成员
};
int main()
{
printf("%d ", sizeof(struct s));
return 0;
}
程序运行
3.使用malloc函数进行柔性数组的空间分配
struct S
{
int n;
char c;
int arr[];
};
int main()
{
//柔性数组创建空间,+号前头的是不包含柔性数组大小的空间,后边是创建了
//元素个数为10的柔性数组
struct S* ps = (struct S*)malloc(sizeof(struct S) + 10 * sizeof(int));
if (ps == NULL)
{
printf("%p\n", strerror(errno));
return 1;
}
//柔性数组的使用
int i = 0;
for (i = 0; i < 10; i++)
{
ps->arr[i] = i + 1;
printf("%d ", ps->arr[i]);
}
//释放
free(ps);
ps = NULL;
}
代码运行