了解C++中的动态对象("new")



我正在努力更深入地理解新运算符。我确实理解它从堆中分配内存并返回一个指向内存的指针的事实。我的问题是,一旦我获得指针并使用它来存储指向另一个声明变量的另一个指针,该值或所指向的值是如何发生的?例如

我申报一个可变

int x = 4;

然后说

int* ptr = new int;
ptr = &x;

ptr从堆中指向一块内存。x是在拥有单独内存块的堆栈中定义的。ptr和x的地址是相同的。如果我删除ptr,x仍然有效,因为它仍然存在于内存中。当我说*ptr时,我正在寻找ptr所指向的值,在本例中为4。我的问题是,4,它在哪里。它存在于两个独立的记忆块中吗。一个用x表示,另一个我刚从new得到。这个过程是如何发生的?4是如何在两个块之间传输的,或者我缺少sthg?请帮忙。

当我说ptr=&x、 是按位复制的。换句话说,我会永远失去刚刚通过堆访问的内存吗?

int* ptr = new int;
ptr = &x;

ptr从堆中指向一块内存

不,不是。赋值后,它指向具有自动存储功能的变量x的地址。您已经丢失了最初由ptr指向的动态分配的int的句柄,因此无法再删除它。4不会在任何"块"内存中传输。当您取消引用ptr时,您将获得x引用的变量,该变量包含值4

试试这个例子:

#include <iostream>
int main()
{
int x = 4;
int* ptr = new int;
ptr = &x;  // lose handle on dynamically allocated int: MEMORY LEAK
std::cout << (*ptr) << "n";
x += 1;
std::cout << (*ptr) << "n";
(*ptr) += 1;
std::cout << x << "n";
}

如您所见,您可以将ptr指向任何想要的地址,但这并不意味着它是安全的。在这里,您正在执行错误的内存操作,因为在new上分配的内存是变形的,而不是由ptr指向的。这是语言允许的,但不安全。

所以4仍然在它们的同一地址,在堆栈上,只是在执行ptr=&x;之后,它也被ptr引用。

忘记"堆栈"one_answers"堆"。这对你需要理解的内容并不重要。

C++中的对象有三个不同的存储类之一:静态、动态和自动。

自动对象和静态对象是指非引用变量的值。更准确地说,命名空间范围的变量和块范围的静态变量包含静态对象,而块范围的非静态变量包含自动对象。这些物体的寿命由它们在源代码中的位置决定:

// file.cpp
int a;             // static, global (= "namespace scope")
void foo()
{
static int b;  // static, block scope
int c;         // automatic (always block scope)
}


相比之下,动态对象正是作为new表达式的结果创建的对象。动态对象本身从来都不是变量。你只能通过指针(它本身就是一个对象)或引用变量(引用从来都不是对象)来获取它们:

Foo * p = new Foo;
Foo & q = *new Foo;  // NEVER do this!

动态对象一直存在,直到您通过指向它们的指针显式删除它们:

delete p;    // normal
delete &q;   // works, but insane

在您的案例中,new int创建了一个类型为int的新的动态对象,并将指向该对象的指针存储在变量ptr中。但是,在下一行中,您将覆盖变量并丢失指向动态整数的指针。您已经泄漏了对象,无法再恢复。

最新更新