C++迭代时删除列表成员:标准解决方案不起作用
C++ deleting a list member while iterating: standard solution is not working?
这是我的问题。我已经阅读了许多关于如何在迭代列表时删除列表成员的先前问题,并尝试了答案提出的各种解决方案。碰巧它们似乎不起作用。我有一个此类类的列表:
class Walker {
public:
Walker(int);
~Walker();
double *x;
double *y;
double *z;
double weight;
int molteplicity;
};
构造函数和析构函数如下
Walker::Walker(int particle_num) {
x = new double[particle_num];
y = new double[particle_num];
z = new double[particle_num];
}
Walker::~Walker() {
delete x;
delete y;
delete z;
}
现在,列表
list<Walker> population;
定义为另一个类的成员。现在,如果元素的摩尔率为空(通过另一个函数计算),我必须动态地从类中删除成员,这就是我的做法:
for( it = population.begin(); it != population.end(); ) {
if( it->molteplicity == 0 ) {
it = population.erase(it);
} else {
++it;
}
在运行时收到以下错误:
prog(22332) malloc: * 对象 0x7f838ac03a60 的错误:指针为 未分配释放 * 在malloc_error_break中设置断点以调试中止陷阱:6
你看到错误了吗?非常感谢您的帮助!!如果您需要更多代码,请告诉我。
这个问题与 std::list
的使用无关,但它在析构函数中:
Walker::~Walker() {
delete x;
delete y;
delete z;
}
您是使用 new[]
而不是 new
进行分配的,因此您必须使用 delete[]
而不是 delete
:
Walker::~Walker() {
delete[] x;
delete[] y;
delete[] z;
}
现场演示
另请注意,molteplicity
和 weight
永远不会初始化,因此可以包含任何数字(可能与 0
不同)。
完成这些更改后,您的程序可以完美编译并运行。
另请注意,new
和delete
在C++社区中通常不受欢迎,这是有充分理由的。使用智能指针或容器,请通常遵循零规则。
最后,您可以使用std::list::remove_if
获得更清洁的解决方案。如果您遵循这些提示,您将获得类似于以下内容的内容:
struct Walker {
Walker(int num)
: x(num), y(num), z(num)
, weight(0)
, molteplicity(0)
{}
std::vector<double> x, y, z;
double weight;
int molteplicity;
};
并用作:
std::list<Walker> population {...};
population.remove_if([](Walker const& w) { return w.molteplicity == 0; });
现场演示
这既更具可读性,也更正确。
你应该实现复制构造函数,因为列表在内部使用它。复制必须在执行如下代码时完成:list.push_back(Walker(5));
.必须将临时对象移动或复制到列表中。默认复制构造函数仅复制指针,因此析构函数将释放相同的内存两次。
在这种情况下,移动语义也足够了:请将此构造函数添加到您的代码中:
Walker(Walker&& other)
{
x = other.x;
y = other.y;
z = other.z;
weight = other.weight;
molteplicity = other.molteplicity;
//remove data from the original object to avoid freeing memory twice
other.x = nullptr;
other.y = nullptr;
other.z = nullptr;
}
并删除复制构造函数(或正确实现它):
Walker(const Walker& other) = delete;
如果您使用指针并分配内存,那么您应该知道三个规则:
三法则(也称为三巨头法则或大三法则) 三)是C++(C++11之前)的经验法则,声称如果 一个类定义它应该显式定义的以下内容之一 定义所有三个:
破坏者
复制构造函数
复制赋值运算符
- 运行同一解决方案的另一个项目的项目
- Project Euler问题4的错误解决方案
- 计算每个节点的树高,帮助我解释这个代码解决方案
- C++:Application.cpp中抛出了未解析的外部符号(解决方案在问题的末尾,供未来的读者参考)
- visual c++,如何获取解决方案目录中的代码
- 有没有办法在远程设备上打开和编辑visual Studio 2017解决方案
- C++Matching Brackets 2解决方案不起作用
- 在 ubuntu3 上C++ goto 定义有什么解决方案吗16.04?
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 我的固定时间步长与增量时间和插值的解决方案是错误的吗?
- 无法在问题解决方案中执行输出逻辑
- 最大的回文产品 - 程序未运行,编写解决方案但无法理解问题
- 从预序遍历构造 bst 的 c++ 和 python 解决方案之间的区别
- 在一个解决方案中针对第三方静态库 (Creo) 的不同版本(版本)进行构建
- 如何巧妙地编写两个函数——一个用于检查是否存在解决方案,另一个用于获取所有解决方案
- 显示字符名称C 名称的标准解决方案
- C++迭代时删除列表成员:标准解决方案不起作用
- /lib64/libc.so.6 的标准解决方案:未找到版本"GLIBC_2.14"
- 标准C++14中零大小数组的解决方案
- 解决方案与命名空间/ADL 事物的标准一致性