如何防止成员函数返回的指针被删除?
How do I prevent deletion of a pointer returned by a member function?
考虑下面的示例代码。类Data
用于存储数据数组:为了简单起见,我选择使用vector<char>
作为数据成员。然而,这些数据必须由一个外部例程处理,它需要一个指向数组第一个元素的指针,当然,还有这个数组的长度:出于这个原因,我还实现了get_data()
和get_length()
函数。
class Data
{
public:
Data(const char* sourcePtr, int sourceLength) : _data(sourcePtr, sourcePtr+sourceLength) { ; }
const char* get_data() const { return &_data.front(); }
int get_length() const { return _data.size(); }
void print() const
{
vector<char>::const_iterator it;
for(it = _data.begin(); it != _data.end(); ++it)
cout << *it;
}
private:
vector<char> _data;
};
现在考虑下面的代码示例,它使用类Data
。
int main(int argc, char** argv)
{
char* a = new char[4];
a[0] = 'b';
a[1] = 'y';
a[2] = 't';
a[3] = 'e';
Data myData(a,4);
delete[] a;
myData.print();
cout << endl;
const char* aPtr = myData.get_data();
// The following statement frees the memory allocated
// for the data member of the class Data.
delete[] aPtr;
return 0;
}
上面的语句delete[] aPtr
释放了为Data
类的数据成员分配的内存。因此,当自动释放myData
对象时,vector<char>
的内容已经被手动释放,显然会出现错误SIGABRT。
如何确保编译器将语句delete[] aPtr
标记为错误?您应该如何修改类Data
来实现这个目标?
处理这个问题最直接的方法是明确谁是指针的"所有者"。在我的c++时代,如果一个函数返回一个指针,函数的名字应该以"Create"开头,而不是"Get"。后来,在这种情况下,我们通常返回智能指针。
在c++中,你不需要显式地删除任何指针,而是将所有指针存储在一个智能指针中,当指针被销毁时,它将删除指针,这实际上一点也不难。停止使用"裸" new
和delete
操作,将new
包装在RAII类型中,除非您正在编写RAII类型的析构函数,否则不要使用delete
。
std::unique_ptr<char[]> a{ new char[4] };
a[0] = 'b';
a[1] = 'y';
a[2] = 't';
a[3] = 'e';
Data myData(std::move(a),4);
这段代码意味着数组的所有权被明确地赋予了智能指针,然后明确地转移给了Data
对象。尝试delete
数组将无法编译。
这并不能阻止用户以后使用delete[] aPtr
,但是如果你养成了从不使用delete
的习惯,除非在RAII类型的析构函数中,那么当有人在不应该使用delete
的地方引入bug时,它就会变得非常明显,因为他们不拥有内存。
不要摆弄指针。如果你的代码的用户不愿意停止这样做,那么让他们以痛苦的方式学习。
你没有。new
和delete
不跟踪指针的所有者。那是你的工作。
你可以做的是复制指针所指向的数据。那么调用者对数组做什么就无关紧要了。你有自己的副本,假设你没有做一些愚蠢的事情,比如把它暴露给任何想要它的人,它是安全的。
或者,查看std::unique_ptr
和std::shared_ptr
。就内存管理而言,它们是新的热点;当你使用智能指针时,内存几乎可以自我管理。
写好文档。阻止其他程序员做傻事不是你的工作。
- 使用函数引用指向节点的指针删除链表中的节点?
- 如何通过指向元组的共享指针删除对象
- 函数内的 C++ 指针删除
- 一个对象的两个指针.删除了一个指针,对象仍然存在
- 如何通过存储在 std::list 中的指针删除对象?
- C++中的智能指针删除
- 将C 中的每个指针删除作为阵列的指针安全吗?
- 使用 C 字符串和指针.删除除小写和空格以外的任何字符
- 在特定情况下,指针删除和铸造之间的关系不清楚
- 提升属性树:使用指向节点及其父节点的指针删除节点
- 警告C4150在尝试包装本机C 类时,指向不完整类型的指针删除
- C++ Valgrind 双指针删除,用于防止内存泄漏
- C 通过指向其基类的指针删除派生对象
- 将指针删除到数组
- 当通过其中一个指针删除对象时,C++将所有指针设置为null
- 智能指针删除器和"using"名称为"pointer"关键字
- 通过指向其基的指针删除 POD 对象是否安全
- 模板化的出列无效指针:删除类时失败
- 使用"this"指针删除
- (C++) list.error 方法和使用指针删除内存