删除删除/删除[]

Remove delete/delete[]

本文关键字:删除      更新时间:2023-10-16

我正在尝试删除旧应用程序的所有delete和delete[],转而使用智能指针。在下面的代码片段中,我想删除cicle的最后一个。

std::unique_ptr<MapiFileDesc> fileDesc(new MapiFileDesc[numFiles]);
for (int i = 0; i < numFiles; ++i)
{
    // Works but I've to delete[] at the end
    fileDesc[i].lpszPathName = new CHAR[MAX_PATH];
    // Does not work. For each iteration the previous array will be deleted
    // It also happens with shared_array
    boost::scoped_array<CHAR> pathName(new CHAR[MAX_PATH]);
    fileDesc[i].lpszPathName = pathName.get();
}
// I want to remove the following cicle
for (int i = 0; i < numFiles; ++i)
{
    delete [] fileDesc[i].lpszPathName;
    fileDesc[i].lpszPathName = nullptr;
}

对于这种情况,你认为最好的方法是什么:使用一个包装器对象来跟踪创建的所有数组并在析构函数中删除它们,或者使用boost::shared_array向量并将它们分配给每个元素?

std::vector<boost::shared_array<CHAR> > objs;
for (int i = 0; i < 10; ++i)
{
    objs.push_back(boost::shared_array<CHAR>(new CHAR[MAX_PATH]));
}

我需要使用boost::shared_ptr,因为我使用的是VC++2008

提前谢谢。J.Lacerda

std::vector<std::string > objs(numFiles, std::string(MAX_PATH, 0));
std::vector<MapiFileDesc> fileDesc(numFiles);
for (int i = 0; i < numFiles; ++i)
    fileDesc[i].lpszPathName=objs[i].data();
// after the C API calls, if you do need to use the strings as C++ strings,
// resync the C++ string length with the C string data
// (not necessary if you just use them via c_str())
for (int i = 0; i < numFiles; ++i)
    objs[i].resize(strlen(objs[i].c_str());

顺便说一句,如果您不需要将整个数组传递给C API,而只需要将单个结构传递给C,那么您可以创建一个存储MapiFileDesc结构和std::string的结构的单个向量,将两个对象的生存期强绑定,并允许构造函数负责将lpszPathName与字符串data()成员链接起来;不过,如果这个结构只用于一个函数,我可能不会介意。

std::unique_ptr<MapiFileDesc[]> fileDesc(new MapiFileDesc[numFiles]);
typedef std::unique_ptr<CHAR[]> CharBuffer;
std::vector<CharBuffer> pathNameBuffers;
for (int i = 0; i < numFiles; ++i)
{
    pathNameBuffers.push_back(CharBuffer(new CHAR[MAX_PATH]));
    fileDesc[i].lpszPathName = pathNameBuffers.back().get();
}

不过,这并不会在结尾处将指针置空。

在尝试减少指针数量/摆脱丑陋的内存管理时,减少deletedelete[]调用的数量并不是唯一可以做的事情。

标准库提供了许多整洁的类,允许您使用具有自动存储持续时间的对象。使用STL容器(如std::vector)代替C样式数组,对于语义上表示字符串的字符数组,请相应地使用std::stringstd::wstring

我喜欢boost共享数组的方法。我认为你面临的问题是boost shared_array中的get()方法没有增加对象的引用计数。以下是您的示例中的一个解决方案,它将增加引用计数。

for (int i = 0; i < numFiles; ++i)
{
    // Works but I've to delete[] at the end
    fileDesc[i].lpszPathName = new CHAR[MAX_PATH];
    // Does not work. For each iteration the previous array will be deleted
    // It also happens with shared_array
    boost::shared_array<CHAR> pathName(new CHAR[MAX_PATH]);
    fileDesc[i].lpszPathName = pathName.get();
    **// Here is a workaround to increase reference count
    boost::shared_array<CHAR> pathNameTemp (pathName);**
}