我正在做一个任务,它涉及更新动态数组的大小以存储重复的输入,值 -1 表示输入结束。当我使用此代码时:
bool end = false;
int curr;
int n = 0;
int* currArr = new int[n];
int* temp = NULL;
while (end == false) {
cin >> curr;
if (curr == -1) {
end = true;
}
else {
n++;
int* temp = new int[n];
temp = currArr;
temp[n - 1] = curr;
currArr = temp;
}
}
delete[] currArr;
delete[] temp;
我是否为 temp 定义了一个内存地址,在每次迭代期间更改存储在该地址的内容,然后在最后干净地删除该地址的内容?
还是我在每次迭代期间分配一个新的动态数组,只删除在最后一次迭代中定义的数组,并泄漏其余数组?如果是这样,我将如何避免这种情况?
同样,如果我在函数中定义一个动态数组,如下所示:
int* fxn(int size) {
int* x = new int[size];
return &x[0];
}
int main() {
int* y = fxn(size);
delete[] y;
return 0;
}
我的理解是,删除 y 将删除数组,因为 y 指向函数中 x 指向的地址相同。如果 fxn 是一个 void 函数,则需要在 fxn 中删除 x,因为 fxn 不会将任何信息输出到用于定位 x
的主线程。我理解正确吗?
谢谢!
每次分配内存并将先前分配的指针分配给新分配的内存时,都应删除前一个指针。否则会导致内存泄漏。在您的情况下,curArr 一直指向循环中的新地址,但永远不会删除以前的地址。然后,您对curArr和temp的删除将崩溃,因为它们指向同一位置,因此您要删除同一指针两次。并且在分配 curArray 后将 temp 辅助到curArray,您只是再次丢失了新分配的指针。所以代码是一个巨大的混乱,充满了泄漏和崩溃。您最初还会分配大小为 0 的内存,这是未定义的行为。
#include <iostream>
#include <memory>
using namespace std;
int main(){
bool end = false;
int curr;
int n = 1;
int* currArr = new int[n];
while (end == false) {
cin >> curr;
if (curr == -1) {
end = true;
}
else {
currArr[n - 1] = curr;
int* temp = new int[n+1];
memcpy(temp, currArr, n*sizeof(int));
delete[] currArr;
currArr = temp;
++n;
}
}
for(int index = 0; index < n-1; ++index){
std::cout << currArr[index]<< std::endl;
}
delete[] currArr;
}
我摆脱了代码中的冗余并修复了泄漏。 该代码最初将分配大小为 n=1 的内存。然后,用户输入 curr 的任何内容都将放置在索引 n-1 处。然后,将使用 temp 将新内存分配给大小为 n+1。curArr 中的先前内存将被复制到新分配的区域中。curArr 的先前区域将被删除,指针将分配给新区域。
是的。你对第二个问题的理解是正确的。
int* temp = new int[n];
这会在动态范围内分配一个新的int
数组,将分配的数组分配给temp
。随即:
temp = currArr;
这将采用新分配的数组temp
,并立即用现有指针currArr
覆盖此指针。新分配的内存泄漏了,什么时候全部说完了,temp
和currArr
现在都是同一个指针值(第二赋值,两行之后,没有改变这一点,已经太晚了)。
delete[] currArr;
delete[] temp;
因此,这最终会两次delete[]
相同的指针值,从而导致未定义的行为、内存损坏和可能的崩溃。
此外,即使循环中的分配是固定的,因此它不会被破坏,因为循环可以执行多次,并且这仅在循环结束时delete
任何事情,因此在任何情况下都无法避免泄漏内存。
我是否正在为 temp 定义内存地址,更改存储在 在每次迭代期间该地址,然后干净地删除内容 最后的那个地址?
否,您正在泄漏内存、损坏内存并导致未定义的行为,并可能导致崩溃。
您需要修复初始分配,这样它就不会被破坏,并在分配新缓冲区(temp
)后立即delete
以前的缓冲区(currArray
),然后最后,将temp
分配给currArray
(复制其内容后)。