int val = 20;//在栈空间上开辟四个字节
char arr[10] = {0};//在栈空间上开辟10个字节的连续空间
观察会发现这两行代码有以下特点:
1.空间开辟⼤⼩是固定的
2.数组在申明的时候,必须指定数组的⻓度,数组空间⼀旦确定了⼤⼩不能调整
注意:C99引入的变长数组在编译时已经确定了空间大小,本质上也是固定的!
接下来开辟的空间都是在堆区!!!
void* malloc (size_t size);
//()里面的是字节多少,单位是字节
//返回是void指针
头文件为:#include
这个函数向内存申请⼀块连续可⽤的空间,并返回指向这块空间的指针。
如果开辟成功,则返回⼀个指向开辟好空间的指针。
#include
#include
int main()
{
int* p = (int*)malloc(10 * sizeof(int));
if (p == NULL)
{
perror(malloc);
return 1;
}
else
{
return 0;
}
}
void free (void* ptr);
头文件为:#include
#include
#include
int main()
{
int* p = (int*)malloc(10 * sizeof(int));
if (p == NULL)
{
perror(malloc);
return 1;
}
else
{
free(p);//free是释放malloc开辟的空间
p = NULL;//但指针p还存放着原地址,要转成空指针
return 0;
}
}
其实程序结束才会被系统收回!!!
void* calloc (size_t num, size_t size);
头文件为:#include
#include
#include
int main()
{
int* pi = (int*)calloc(10, sizeof(int));
if (pi == NULL)
{
perror(calloc);
return 1;
}
else
{
printf("%d ", *(pi + 0));
printf("%d ", *(pi + 1));
printf("%d ", *(pi + 2));
printf("%d ", *(pi + 3));
printf("%d ", *(pi + 4));
printf("%d ", *(pi + 5));
printf("%d ", *(pi + 6));
printf("%d ", *(pi + 7));
}
//释放空间
free(pi);
pi = NULL;
return 0;
}
void* realloc (void* ptr, size_t size);
头文件为:#include
#include
#include
int main()
{
int* pi = (int*)calloc(10, sizeof(int));
if (pi == NULL)
{
perror(calloc);
return 1;
}
//打印
for (int i = 0; i <= 10; i++)
{
*(pi+i) = i;
printf("%d ", *(pi + i));
}
//空间不够
int* ptr = (int*)realloc(pi, 12 * sizeof(int));
if (ptr == NULL)
{
perror(realloc);
return 1;
}
pi = ptr;
free(pi);
pi = NULL;
return 0;
}
1.对NULL指针的解引⽤操作
void test()
{
int *p = (int *)malloc(INT_MAX/4);
*p = 20;//如果p的值是NULL,就会有问题
free(p);
}
问题所在:未对p进行检查,可能空间开辟失败,所以要先检查再使用。
2.对动态开辟空间的越界访问
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;//当i是10的时候越界访问
}
free(p);
}
问题所在:i=10时空间不够,还有就是free之后未进行p=NULL。
void test()
{
int a = 10;
int *p = &a;
free(p);//ok?
}
问题所在:同上一个问题!
void test()
{
int *p = (int *)malloc(100);
p++;
free(p);//p不再指向动态内存的起始位置
}
问题所在:指针起始位置变动,所以free(p)释放的空间不是全部!
5.对同⼀块动态内存多次释放
void test()
{
int *p = (int *)malloc(100);
free(p);
free(p);//重复释放
}
问题所在:对一个开辟的空间多次释放!
6.动态开辟内存忘记释放(内存泄露)
void test()
{
int *p = (int *)malloc(100);
if(NULL != p)
{
*p = 20;
}
}
int main()
{
test();
while(1);
}
问题所在:没有对开辟的空间进行释放!
忘记释放不再使⽤的动态开辟的空间会造成内存泄漏。 切记:动态开辟的空间⼀定要释放,并且正确释放。
最后,祝各位学习进步!