0

我在使用newanddelete运算符时遇到了一个小问题。我在很多地方读到每个new运算符都必须与 a 相对应delete,据我所知,使用创建的变量new将持续存在,直到它们被 that 击中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;
}

我有两个问题:

  1. 我认为testFunction1(),我正在按值返回指针。但我不知道如何解决这个问题,返回对指针的引用,以便我可以在 main 方法(或任何其他方法)中释放内存。

  2. 为什么我在取消引用时得到 5 作为输出*ptr1?我的意思是,从地址输出中,很明显分配给cin的值testFunction2()存储在那里,但为什么会发生这种情况呢?

4

2 回答 2

1

您正在将指针设置为在堆栈上分配的变量:

int a = 5, b = 10;
int* pointerToInt1 = new int; // allocates an int on heap
pointerToInt1 = &a; // overwrite pointer with a local variable

发生的情况是,您返回的指针指向一个在堆栈上具有自动分配的值,因此当函数退出其范围时,pinter 变得无效。

此外,由于您丢失了对在堆上动态分配的对象的任何引用,因此您无法再删除它,因此它是内存泄漏。

最后 delete 尝试删除一个指针,该指针指向在调用期间位于堆栈上的地址,testFunction1因此它不再是有效指针,因此delete不起作用。

于 2013-01-27T05:10:45.297 回答
1

让我们不要把你的问题放在一边,先解释你的代码。

您声明并定义了一个名为testFunction1返回intpoitner的函数

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
}

调用 function 后testFunction1,仍然需要删除动态分配的内存块。

int *p = testFunction1();
delete p;

现在,如果您回过头来复习您的两个问题,您得到答案了吗?

于 2013-01-27T07:18:33.753 回答