前言
当我们的需要自己申请内存空间的大小,而不想通过编译器取申请内存空间时,可以使用内存动态内配技术,这时候申请的内存空间都在堆中,而不是在栈中一、malloc,calloc,realloc
malloc:C标准库函数
int main() {
unsigned x;
std::cin >> x;
int* p = (int*)malloc(x * sizeof(x));
if (p == nullptr)
{
std::cout << "内存分配失败!";
}
else {
p[0] = 1;
p[1] = 2;
p[2] = p[0] * p[1];
std::cout << p[0] << " " << p[1] << " " << p[2];
}
system(0);
return 0;
}
calloc:C标准库函数,运行效率低比malloc低
int main() {
unsigned x;
std::cin >> x;
int* p{}, * pm{};
pm = (int*)malloc(x * sizeof(int));
p = (int*)calloc(x, sizeof(x));
std::cout << pm[0] << std::endl;
std::cout << p[0] << std::endl;
system(0);
return 0;
}
realloc():重新分配内存
地址会不会改变取决于重新分配的内存比原来的内存大还是小
int main() {
unsigned x;
std::cout << "请输入要分配的内存大小:";
std::cin >> x;
int* p{}, * pold;
p = (int*)calloc(x, sizeof(int));
pold = p;
std::cout << p[0] << std::endl;
if (p == nullptr)
{
std::cout << "内存分配失败!";
}
else {
p[0] = 1;
p[1] = 2;
p[2] = p[0] * p[1];
std::cout << p[0] << " " << p[1] << " " << p[2];
}
std::cout << "请输入要重新分配的内存大小!";
std::cin >> x;
p = (int*)realloc(p, x);
std::cout << p << "----" << pold << std::endl;
std::cout << p[0] << " " << p[1] << " " << p[2];
return 0;
}
二、free
作用:释放内存,一般释放后会将对应的内存指针置空,避免悬空指针的出现
free(p);
p = NULL;
三 new int, new int[]
C++的内存分配运算符,基于C语言的内存分配malloc()实现的new运算符重载函数
int* pInt = new int;
int* pInt2 = new int[2];
四 delete, delete[]
C++的内存释放运算符
int* pInt = new int;
delete pInt;
int* pInt2 = new int[2];
delete[] pInt2;
五 内存分配的风险
1.悬空指针的问题:指针最初指向的内存已经被释放了的一种指针
解决方案1:释放后把对应的指针设置为nullptr,运行起来后编译器会报错!
int main() {
int* p = nullptr;
int* p2 = new int;
p = p2;
delete p2;
p = p2 = nullptr;
*p = 1;
}
解决方案2:使用智能指针
2.野指针问题:没有被初始化过的指针
解决方案1:对于指针初始化时都是赋值为 nullptr ,这样在使用时编译器就会直接报错,产生非法内存访问。
int* p = nullptr;
std::cout << *p << std::endl;
return 0;
解决方案2:养成好的编程习惯,定义指针变量及时初始化
3.重复释放问题:多线程环境下容易造成指针变量的多次释放
解决方案:没有解决方案,只能编码的时候提高警惕性
4.内存碎片问题:待研究(嵌入式开发比较严格,可能会有这样的问题)
六 复制内存
1.for循环
int main() {
int a[5]{ 1,2,3,4,5 };
int* b = new int[5];
for (int i = 0; i < 5; i++)
b[i] = a[i];
for (int u = 0; u < 5; u++)
std::cout << b[u] << std::endl;
}
2.memcpy(…): C语言标准库函数
int main() {
int a[5]{ 1,2,3,4,5 };
int* b = new int[5];
memcpy(b, a, sizeof(a));
for (int u = 0; u < 5; u++)
std::cout << b[u] << std::endl;
}
3.memset(…): C语言标准库函数
int main() {
int a[5]{ 1,2,3,4,5 };
int* b = new int[5];
memset(a, 0x1234 /*只能一个字节一个字节的初始化*/ , sizeof(a));
memcpy(b, a, sizeof(b));
for (int u = 0; u < 5; u++)
std::cout << std::hex << a[u] << std::endl;
}
作用:常用于初始化内存空间为0或-1;