我会使用生成函数内部的静态变量来执行此操作,该变量返回指向数组的指针。然后,在你的 delete 函数中,只需调用 generate 函数给你指针并删除它。要删除在 HEAP 上创建的数组,请使用 delete[] 运算符。应该调用此运算符来释放分配给new Type[] 的内存,其中Type 是任何类型(例如int)。删除(也称为解除分配)此内存后,将指向数组开头的指针设置为nullptr 几乎总是一个好主意。这样,您就不会意外地再次使用该指针。
这里有一些代码来说明我的意思:
int* getArray(unsigned long long elements_num = 0)
{
static int* arr = nullptr;
if (arr == nullptr && elements_num > 0)
{
arr = new int[elements_num];
std::cout
<< "Address of array being created: " << arr
<< std::endl;
}
return arr;
}
void deleteArray()
{
int* arrayAddress = getArray();
if (arrayAddress == nullptr)
{
std::cerr << "Array not yet created" << std::endl;
}
else
{
std::cout
<< "Address of array being deleted: " << arrayAddress
<< std::endl;
delete[] arrayAddress;
arrayAddress = nullptr;
}
}
int main()
{
constexpr unsigned long long ARR_SIZE = 5;
std::cout
<< "Trying to delete before creating array..."
<< std::endl;
deleteArray();
std::cout << '\n'
<< "Creating array with 5 elements..."
<< std::endl;
int* myArray = getArray(ARR_SIZE);
std::cout << '\n'
<< "Setting the values of the elements..."
<< std::endl;
for (unsigned long long i = 0; i < ARR_SIZE; i++)
{
myArray[i] = static_cast<int>(i) + 1;
}
std::cout << "Values: ";
for (unsigned long long i = 0; i < ARR_SIZE; i++)
{
std::cout << myArray[i] << ", ";
}
std::cout << "\n\n"
<< "Deleting array..."
<< std::endl;
deleteArray();
deleteArray(); // Trying to delete twice... Our program should be fine, right?
}
这是我运行它得到的输出:
Trying to delete before creating array...
Array not yet created
Creating array with 5 elements...
Address of array being created: 01147438
Setting the values of the elements...
Values: 1, 2, 3, 4, 5,
Deleting array...
Address of array being deleted: 01147438
Address of array being deleted: 01147438
[Program crashes]
编辑 1
然而,不要这么快就无条件接受。还有一个大问题。如果再次调用deleteArray(),它会再次尝试删除内存。为什么是这样?我们不是将数组设置回nullptr 吗?嗯……是的,不是的。
要理解,想想指针是什么;它只是一个变量。而且,就像任何其他变量类型一样,指针占用内存。这就像有一本书在你的办公桌上占据了很大的位置,但在冰箱上贴了一张便条,告诉你你的书在哪里。在这种情况下,note 是一个指针,而 book 是一个非指针变量。
现在,假设您在浴室里有另一张纸条,告诉您冰箱上的纸条在哪里。第二个音符就像一个双指针。双指针只是存储普通指针的内存位置。
回到问题。当我们调用getArray 时,我们所做的是我们创建了第二个指针变量(它有它自己的内存地址)。因此,当我们将第二个指针设置为nullptr 时,这并不意味着我们也将原始指针设置为nullptr。这就像冰箱上的便条和客厅里的便条都告诉您书在哪里。如果您擦除了客厅便条上的内容,这并不意味着您也擦除了冰箱上便条上的内容。
那么我们该如何解决这个问题呢?我们必须使用双指针。使用双指针意味着,当我们取消引用该指针一次时,我们会得到 原始 数组的实际内存地址。
问题是,一直弄乱双指针看起来是相当可怕的,所以我们可以制作一个让事情变得更容易忍受的函数,并且只在我们需要将原始数组设置为 @ 时才使用双指针987654333@。
这是我们的带有双指针的新代码:
// Notice the change in return type here
int** getArrayAddress(unsigned long long elements_num = 0)
{
static int* arr = nullptr;
if (arr == nullptr && elements_num > 0)
{
arr = new int[elements_num];
std::cout
<< "Address of array being created: " << arr
<< std::endl;
}
// Notice the return went from "arr" to "&arr"
return &arr;
}
void deleteArray()
{
// Notice the change in variable type here
int** arrayAddress = getArrayAddress();
if (*arrayAddress == nullptr)
{
std::cerr << "Array not yet created" << std::endl;
}
else
{
std::cout
<< "Address of array being deleted: " << *arrayAddress
<< std::endl;
// Notice we have to dereference once before deleting
delete[] *arrayAddress;
*arrayAddress = nullptr;
}
}
// This is our convenience function so we don't have to mess with
// double pointers all the time
int* getArray(unsigned long long elements_num = 0)
{
return *getArrayAddress(elements_num);
}
int main()
{
constexpr unsigned long long ARR_SIZE = 5;
std::cout
<< "Trying to delete before creating array..."
<< std::endl;
deleteArray();
std::cout << '\n'
<< "Creating array with 5 elements..."
<< std::endl;
int* myArray = getArray(ARR_SIZE);
std::cout << '\n'
<< "Setting the values of the elements..."
<< std::endl;
for (unsigned long long i = 0; i < ARR_SIZE; i++)
{
myArray[i] = static_cast<int>(i) + 1;
}
std::cout << "Values: ";
for (unsigned long long i = 0; i < ARR_SIZE; i++)
{
std::cout << myArray[i] << ", ";
}
std::cout << "\n\n"
<< "Deleting array..."
<< std::endl;
deleteArray();
deleteArray(); // Now the program really can handle this
}
这是它的输出:
Trying to delete before creating array...
Array not yet created
Creating array with 5 elements...
Address of array being created: 00C573A0
Setting the values of the elements...
Values: 1, 2, 3, 4, 5,
Deleting array...
Address of array being deleted: 00C573A0
Array not yet created