目录
1. 为什么存在动态内存分配
int a=100; // 在栈空间上开辟四个字节char arr [ 10 ] = { 0 }; // 在栈空间上开辟 10 个字节的连续空间
(1) 空间开辟大小是固定的。(2) 数组在申明的时候,必须指定数组的长度,它所需要的内存在编译时分配。
2. 动态内存函数的介绍
2.1 malloc
注意事项:
(1)这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。
(2)如果开辟成功,则返回一个指向开辟好空间的指针。
(3)如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查
(4)返回值的类型是 void* ,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己 来决定。
(5)如果参数 size 为0,malloc的行为是标准是未定义的,取决于编译器。
动态申请的内存不会主动释放。
2.2free
注意事项:
(1)如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。
(2)如果参数 ptr 是NULL指针,则函数什么事都不做。
例子:
#include<stdio.h>
#include<stdlib.h>
int main()
{
int* p = NULL;
p = (int *)malloc(10 * sizeof(int));
if (p == NULL)
{
perror("malloc");
return 1;
}
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d\n", *(p + i));
}
free(p);
p = NULL;
return 0;
}
2.3 calloc
注意事项:
(1)函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为0。
(2)与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。
#include<stdio.h>
#include<stdlib.h>
int main()
{
int* p = NULL;
p = (int *)calloc(10 , sizeof(int));
if (p == NULL)
{
perror("calloc");
return 1;
}
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d\n", *(p + i));
}
free(p);
p = NULL;
return 0;
}
2.4realloc
(2)原有空间之后没有足够大的空间
在堆空间上另找一个合适大小 的连续空间来使用。这样函数返回的是一个新的内存地址。
对情况二的小结:(1)开辟新的空间
(2)将旧空间的数据拷贝到新空间
(3)释放旧空间
(4)返回新空间的地址
图解2-1
图解2-1
#include<stdio.h>
#include<stdlib.h>
int main()
{
int* p = NULL;
p = (int *)malloc(10 * sizeof(int));
if (p == NULL)
{
perror("malloc");
return 1;
}
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = i;;
}
int* pp = (int *)realloc(p, 20 * sizeof(int));
if (pp != NULL)
{
p = pp;
pp = NULL;
}
else
{
p = NULL;
perror("realloc");
return 1;
}
for (i = 0; i < 20; i++)
{
printf("%d\n", *(p + i));
}
free(p);
p = NULL;
return 0;
}
注意:
(1)realloc(NULL,10*sizeof(int))==malloc(10*sizeof(int))
(2)减少空间,原数据可能会丢失。
3.经典的笔试题
#include<stdio.h>
#include<stdlib.h>
void GetMemory(char* p)
{
p = (char*)malloc(100);
}
void Test(void)
{
char* str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}
int main()
{
Test();
return 0;
}
分析:
(1)strcpy(str, "hello world")中str为NULL,对NULL进行了解引用操作,程序会崩溃。
(2)p = (char*)malloc(100);形参变量p虽被销毁,但malloc申请的空间没有被释放,内存泄漏。
改正:
#include<stdio.h>
#include<stdlib.h>
void GetMemory(char** p)
{
*p = (char*)malloc(100);
}
void Test(void)
{
char* str = NULL;
GetMemory(&str);
strcpy(str, "hello world");
printf(str);
}
int main()
{
Test();
return 0;
}
题目2:
请问运行Test 函数会有什么样的结果?
#include<stdio.h>
#include<stdlib.h>
char* GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char* str = NULL;
str = GetMemory();
printf(str);
}
int main()
{
Test();
return 0;
}
分析:
图3-1
改正:
#include<stdio.h>
#include<stdlib.h>
char* GetMemory(void)
{
static char p[] = "hello world";
return p;
}
void Test(void)
{
char* str = NULL;
str = GetMemory();
printf(str);
}
int main()
{
Test();
return 0;
}
就是char p[]前加个static.
总结:;例2可统称为返回栈空间地址的问题。
以上为我个人的小分享,如有问题,欢迎讨论!!!