1

我正在尝试删除旧应用程序的所有 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.拉塞尔达

4

4 回答 4

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结构和std::string,强烈绑定两个对象的生命周期并允许构造函数来处理lpszPathName与字符串data()成员的链接;不过,如果这个结构仅用于单个函数,我可能不会打扰。

于 2013-08-28T14:30:01.877 回答
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();
}

不过,这并没有使最后的指针无效。

于 2013-08-28T14:22:33.903 回答
1

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

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

于 2013-08-28T14:25:33.727 回答
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);**
}
于 2013-08-28T16:53:54.197 回答