新建和删除混淆
New and delete mix ups
我在使用 new
和 delete
运算符时遇到了一个小问题。我在很多地方读到每个new
运算符都必须对应于一个delete
,据我了解,用new
创建的变量将一直存在,直到它们被该delete
击中为止。如果您愿意查看以下代码,它很长但很简单:
#include <iostream>
using namespace std;
int* testFunction1();
int* testFunction2();
int main(){
int* ptr1 = testFunction1();
int* ptr2 = testFunction2();
cout << *ptr1 << endl; // outputs 5
cout << *(ptr1 - 1) << endl; // outputs random int
cout << *ptr2 << endl; // outputs random int
cout << ptr1 << endl; //prints address of b from testFunction1()
cout << ptr1 - 1 << endl; // prints address of a and c from testFunction1()
cout << ptr2 << endl; // prints address of a and c from testFunction1()
cout << endl;
// delete ptr1; won't work
return 0;
}
int* testFunction1(){
int a = 5, b = 10;
int* pointerToInt1 = new int;
pointerToInt1 = &a;
pointerToInt1 = &b;
cout << &a << endl;
cout << &b << endl;
return pointerToInt1;
}
int* testFunction2(){
int c = 5;
int* pointerToInt2 = &c;
cout << &c << endl;
return pointerToInt2;
}
我有两个问题:
我认为,使用
testFunction1()
,我按值返回指针。但是我不知道如何解决这个问题,返回对指针的引用,以便我可以释放 main 方法(或就此而言,任何其他方法)中的内存。为什么当我取消引用 5 时得到 5 作为输出
*ptr1
?我的意思是,从地址输出中,很明显分配给c
的值存储在testFunction2()
,但为什么会这样呢?
我们不要把你的问题放在一边,先解释你的代码。
声明并定义了一个名为 testFunction1
的函数,该函数返回 int
poitner
int* testFunction1(){
int a = 5, b = 10; // define local variables with initial values. a,b have different memory addresses
int* pointerToInt1 = new int; // dynamic allocate pointer(new address) to int
pointerToInt1 = &a; // set pointerToInt1 to point to address of a
pointerToInt1 = &b; // set pointerToInt1 to point to address of b
cout << &a << endl;
cout << &b << endl;
return pointerToInt1; // return pointerToInt1 pointer which currently points to address of b
}
a,b
函数testFunction1
中的局部变量,它们具有自动持续时间,当函数完成时,它们被释放,因此pointerToInt1
实际上是悬空指针并访问它是未定义的行为。
此外,testFunction1
中引入了典型的内存泄漏,由new
分配的原始内存块丢失。
int* pointerToInt1 = new int;
pointerToInt1 = &a;
现在,让我们"fix"
函数testFunction1
,是的,我的意思是用双引号修复。
int* testFunction1(){
int a = 5, b = 10;
int* pointerToInt1 = new int;
*pointerToInt1 = a; // copy a to memory pointerToInt1
*pointerToInt1 = b; // copy b to memory pointerToInt1
cout << &a << endl;
cout << &b << endl;
return pointerToInt1; // return pointerToInt1 pointer
}
调用函数 testFunction1
后,仍然需要删除动态分配的内存块。
int *p = testFunction1();
delete p;
现在,如果您回过头来回顾您的两个问题,您会得到答案吗?
您正在设置指向堆栈上分配的变量的指针:
int a = 5, b = 10;
int* pointerToInt1 = new int; // allocates an int on heap
pointerToInt1 = &a; // overwrite pointer with a local variable
发生的情况是,您返回的指针指向在堆栈上自动分配的值,因此当函数退出其范围时,pinter 将变为无效。
此外,由于您丢失了对堆上动态分配的对象的任何引用,因此无法再删除它,因此它是泄漏的内存。
最后,删除尝试删除指向在调用testFunction1
期间堆栈上的地址的指针,因此它不再是有效的指针,因此delete
不起作用。
- 创建模板类型而不新建/删除
- C++ 在请求特定字节的新建后删除
- 为什么非放置"新建"和"删除"内置于语言中,而不仅仅是常规函数?
- 来自C#的mingw DLL:为什么我必须覆盖新建/删除?
- C++ - 定义自定义新建和删除运算符时make_shared
- 使用安全零内存新建/删除时出现问题
- 奇怪的内存泄漏由C++中的新建/删除
- CRT 检测到应用程序在堆缓冲区(新建/删除)类结束后写入内存
- 无法覆盖C++中纯抽象类中的运算符删除/新建
- 编译器或标准C++库 - 新建和删除
- 混合运算符和表达式新建/删除
- 新建和删除的经验法则
- 运算符新建和删除重载作用域
- 使用运算符重载(新建/删除)实现单例的优缺点
- 忽略全局覆盖的新建/删除
- C++内存泄漏新建并删除
- 基本的新建/删除操作员日志记录
- C++自定义全局新建/删除覆盖系统库
- 为什么使用XXXX_new和XXXX_free而不是新建和删除
- 新建和删除如何工作以及它们的存储位置