删除删除/删除[]

时间:2013-08-28 14:17:40

标签: c++ visual-c++ memory-management smart-pointers raii

我正在尝试删除旧应用程序的所有删除和删除[],而是使用智能指针。在下面的代码片段中,我想删除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

4 个答案:

答案 0 :(得分:10)

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而只需要传递单个结构,你可以创建一个结构的单个向量来存储MapiFileDesc结构和{{1 ,强烈绑定两个对象的生命周期,并允许构造函数负责链接std::string与字符串lpszPathName成员;如果这个结构只用在一个函数中,我可能不会打扰。

答案 1 :(得分:1)

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();
}

尽管如此,这并没有使指针无效。

答案 2 :(得分:1)

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

标准库提供了许多简洁的类,允许您使用具有自动存储持续时间的对象。使用诸如std::vector之类的STL容器而不是C风格的数组,以及在语义上表示字符串的字符数组,相应地使用std::stringstd::wstring

答案 3 :(得分:0)

我喜欢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);**
}