我试图了解C ++中的内存管理,所以我一直在写纸牌游戏(有纸牌列表),但是没有使用vector
。
可以说我有Card
这样的数组:Card** cards
。
现在,我想用另一张卡替换一张名为Card* remove
的卡。
我认为必须使用Card*
创建cards
中的所有new
,因为其他功能需要通过指针访问它们。因此,当我从cards
删除元素时,我也应该delete
。
但是,当我调用delete remove
时,似乎弄乱了我的数组。具体来说,假设remove
恰好位于索引2。显然,在delete
,cards[2] == remove
之前。但是,在delete
之后,cards[2]
和remove
都发生了变化,而指向cards
的指针是相同的。
这可能不是一件坏事,但是我对为什么它发生感到非常困惑。理想情况下,我将能够删除位于remove
的堆中的内存,而无需完全修改cards
。我想念什么?
答案 0 :(得分:1)
我编写了一个示例代码来说明您所说的内容。但是我没听见你说的话。
如果您能显示代码(最小且可复制的示例),我们将能够找到发生的情况。
删除指针不会更改指针值,但会释放指针值。
以下是示例:
int main()
{
typedef int Card;
Card ** arr;
// ---------- Init ----------
arr = new Card* [5]; // five cards
for(size_t i = 0; i < 5; ++i)
{
arr[i] = new Card(static_cast<int>(i));
}
// --------------------------
// Direct removal
std::cout << arr[2] << ": " << *arr[2] << '\n';
delete arr[2];
std::cout << arr[2] << '\n'; // >>>>> The address did not change after the deletion
arr[2] = nullptr;
std::cout << std::endl;
// Delegated removal
Card * to_remove = arr[3];
std::cout << to_remove << " / " << arr[3] << " : " << *arr[3] << '\n';
delete to_remove;
std::cout << to_remove << " / " << arr[3] << '\n'; // >>>>> The address still did not change after deletion
arr[3] = nullptr;
// ----- Release memory -----
for(size_t i = 0; i < 5; ++i)
delete arr[i];
delete[] arr;
// --------------------------
return 0;
}
输出:
0x2ea1c30: 2
0x2ea1c30
0x2ea5f40 / 0x2ea5f40 : 3
0x2ea5f40 / 0x2ea5f40
如您所见,指针值没有改变。
我认为重要的是要注意,您应该将已删除的指针设置为nullptr
,因为即使删除后它们仍在Card
列表中。