gpt4 book ai didi

c++ - 从指针 vector 中删除元素并释放之前通过新运算符分配的动态内存?

转载 作者:行者123 更新时间:2023-11-30 03:38:27 25 4
gpt4 key购买 nike

我想向您展示这个非常简单的示例,目的是对一些动态分配的字符串进行排序并清除重复项,调整 vector 大小并释放无用的占用内存。

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

void print_v (vector<string *>& v)
{
cout << "----" << endl;
for (string*& str : v)
cout << *str << " ";
cout << endl << "----" << endl;
}

typedef string * string_ptr;

int main()
{
vector<string_ptr> v;
v.push_back(new string("aba"));
v.push_back(new string("baba"));
v.push_back(new string("saba"));
v.push_back(new string("aba"));
v.push_back(new string("naba"));
v.push_back(new string("aba"));
v.push_back(new string("saba"));
v.push_back(new string("laba"));

print_v(v);

sort(v.begin(), v.end(), [](const string_ptr &a, const string_ptr &b){
return a->compare(*b) < 0;
});

auto last = unique(v.begin(), v.end(), [](const string_ptr &a, const string_ptr &b) {
return a->compare(*b) == 0;
});

print_v(v);

for_each(last, v.end(), [](string_ptr &a){
delete a; //if I comment this line everything works "fine"
a = nullptr;
});

v.erase( find(v.begin(), v.end(), nullptr) , v.end() );

print_v(v);
}

为什么这种东西不起作用?如果我用 delete 评论该行,一切正常,但我当然有内存泄漏。另一个问题:如果在 lambda 函数的签名中我使用 string*(而不是 typedef string_ptr),我会遇到严重的编译错误,为什么?

抱歉我的英语不好,我希望问题足够清楚。

最佳答案

如前所述,std::unique 函数基本上使那些位于返回的迭代器僵尸元素右侧的项目。它们可以被访问,但是它们是无用的。这就是为什么当您将 delete 应用于这些项目时它无法正常工作。

如果您的目标是划分唯一项目,但同时保持其有效性,您可能要使用的算法函数是 std::stable_partition , 使用 std::set。因此,代替 std::unique,您可以执行以下操作:

#include <algorithm>
#include <set>
//...
std::set<std::string> stringset;
auto last = std::stable_partition(v.begin(), v.end(), [&stringset](const string_ptr& a)
{
if ( stringset.count(*a) ) return false;
stringset.insert(*a); return true;
});

基本上,我们使用 std::set 来存储我们最初找到的值。在对 lambda 函数的后续调用中,我们通过查询 set::count() 函数来检查重复项。如果它返回 1,则该项目已经存在于集合中,否则返回 0。因此,要将重复的项目放在分区的右侧,我们需要返回 false,而全新的项目,我们返回 true(并且我们将项目添加到如果是新项目则设置)。所以基本上,我们通过使用 std::stable_partition 编写了 std::unique 的非破坏性版本。

因此,这导致唯一项不仅被划分到 std::stable_partition 的返回迭代器的右侧,而且这些项是完全有效的,可以用于您认为合适的任何目的(在您的情况下,您想要删除它们)。

请注意,这是有效的,如 Live Example 所示

此外,您可以使用 std::partition,但此函数不会保留项目的相对顺序。您可能想改用 std::partition,但我假设您希望保持元素的顺序。

关于c++ - 从指针 vector 中删除元素并释放之前通过新运算符分配的动态内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39598883/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com