所以我必须做一个项目,我需要实现array
,list
,binary heap
,binary tree
和red-black tree
然后衡量他们的表现,比较他们并得出一些结论。现在,规则是这样的:
std::
(仅cout
,可能是string
),Boost
所以我迈出了第一步,实现了一个数组。它看起来像这样:
array.h
#pragma once
#include <iostream>
class array
{
int elements;
int *table;
public:
array();
array(int *t, int n);
int size() const;
int *get() const;
};
array.cpp
#include "array.h"
array::array(int *t, int n) : elements(n), table(new int[elements])
{
memcpy(table, t, elements * sizeof(int));
}
int array::size() const
{
return elements;
}
int *array::get() const
{
return table;
}
该程序基本上具有类似菜单的结构,使用简单的switch
和5个不同的菜单进行5个竞赛。现在,我必须实现删除/添加元素,打印出数组等。我有一个代码将打印出一行数组:
int *p = myArray.get();
int s = myArray.size();
std::cout << "[";
for (int i = 0; i < myArray.size(); i++)
{
if (s - i == 1) std::cout << *(p + i) << "]" << '\n';
else std::cout << *(p + i) << ", ";
}
delete p;
我很好奇的是我写的最后一行。首先我没有使用delete
,因为在这个代码块中没有任何地方存在new
运算符。但后来我想,是的,它会导致内存泄漏,我已经添加了这条线。两种方式都有效。我的问题是:哪一个是正确的?在这种情况下,我是否应该删除pointer
?
答案 0 :(得分:3)
&#39;删除&#39;一个指针将释放它指向的内存,无论它是一个副本还是原始的&#39;。这是因为它只保存一个内存地址(或内存地址的副本),而不是实际的内存。
此外,当您访问已释放的内存时,您无法保证返回给您的数据是您想要/期望的数据,因此您应该只在其所有者的析构函数中删除指针,或者您确定你不再需要它们了。
使用new
或new[]
时,您应始终使用正确的delete
或delete[]
对应方。
答案 1 :(得分:2)
只要您使用new
(或new[]
),就需要匹配delete
(或delete[]
),因此您需要删除{指向的数组{1}}某个地方。 array::table
的析构函数通常是执行它的地方,因为array
拥有该数据。这样,只要array
超出范围,您的array
数据就会被删除。请记住rule of three。如果您的类拥有某些资源,则应覆盖默认的复制构造函数,复制运算符和析构函数。
您似乎误解了array
的作用。 delete
删除动态分配的对象,而不是指针。执行delete
后,您会遇到以下情况:
int *p = myArray.get();
当您致电+-----------+
| myArray |
| +-------+ | +-------+
| | table | | | p |
| +---+---+ | +-------+
+-----|-----+ |
| +------+
| |
+v-v-----------------------+
| allocated data |
+--------------------------+
或delete[] table
时,您最终会得到以下信息:
delete[] p
+-----------+
| myArray |
| +-------+ | +-------+
| | table | | | p |
| +---+---+ | +-------+
+-----|-----+ |
| +------+
| |
v v
Nothing here anymore, but the pointers still point here.
和myArray.table
指向的数组都消失了,因此在指向用于保存该数组的内存的指针上调用p
时的行为未定义。
答案 2 :(得分:0)
您可以考虑动态资源的所有权。
所有权意味着当没有人再使用它时,有人有责任释放它。如果你的array
创建资源,最好让它在析构函数中由他自己释放。创建资源的人自然是所有者。
如果您打算让外面的人获得指针,int* p
,并将其释放,delete p
(应该是delete [] p
),那么您将拥有所有权{{1 }}。您的p
需要知道它不再拥有它,并且不允许array
删除它。
当所有权明确明确时,资源泄露或双重删除的机会就会减少。
顺便说一下,这里有一些代码提示。
array
与p = new T
配对; delete p
与p = new T[]
delete p []
来表示元素的数量。size_t
可以使用int* t
这样的常量。它不需要const int* t
可变。