- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试为我的 TurtleProgram 类创建一个重载的 + 运算符,它存储一个动态分配的字符串数组。但是方法返回的时候调用了析构函数,里面的delete操作抛出异常“Invalid address specified to RtlValidateHeap”。
下面是重载运算符定义、析构函数、默认构造函数、复制构造函数和重载运算符方法中使用的调整大小方法定义。
我已经对这个错误进行了研究,但我没能找到任何与我的问题相关的问题。
// overloaded + operator
// postconditions: returns a new TurtleProgram object that is the sum of two TurtleProgam instruction arrays
TurtleProgram TurtleProgram::operator+(const TurtleProgram &that)
{
TurtleProgram returnTP;
returnTP.resize(this->size_ + that.size_);
for (int i = 0; i < this->size_ + that.size_; i++)
{
if (i < this->size_)
{
returnTP.instructions_[i] = this->instructions_[i];
}
else
{
returnTP.instructions_[i] = that.instructions_[i - this->size_];
}
}
return(returnTP);
}
// resize: resized the array to be of a new size
// preconditions: the new size must be a positive integer
// postconditions: the array is resized, and size is updated
void TurtleProgram::resize(int newSize)
{
string *temp = new string[newSize];
// iterate through, transferring the contents from the old array to the resized array, then setting any empty spaces to ""
for (int i = 0; i < newSize; i++)
{
if (i < size_)
{
temp[i] = instructions_[i];
}
else
{
temp[i] = "";
}
}
if (size_ != 0)
{
delete instructions_;
}
instructions_ = temp;
size_ = newSize;
}
// Default constructor: initializes as an empty array
// postconditions: a new TurtleProgram object is made with an empty array and a size of 0
TurtleProgram::TurtleProgram()
{
instructions_ = new string[0];
size_ = 0;
}
// Default destructor: deallocates instructions_ before destroying the object
// postconditions: the memory is released, and the object destroyed
TurtleProgram::~TurtleProgram()
{
if (size_ != 0)
{
delete instructions_;
}
}
TurtleProgram& TurtleProgram::operator=(const TurtleProgram &that)
{
resize(that.getLength());
for (int i = 0; i < size_; i++)
{
this->instructions_[i] = that.instructions_[i];
}
return(*this);
}
任何人都可以发现我做错了什么/不理解吗?在此先感谢您的帮助,对于任何发布错误,我们深表歉意。这是我的第一个问题!
最佳答案
主要问题是缺少复制构造函数(参见 rule of three)!
TurtleProgram::TurtleProgram(TurtleProgram const& that)
: TurtleProgram()
{
*this = that;
}
请注意,即使在像这样的表达式中
TurtleProgram x, y;
TurtleProgram z = x + y;
将调用复制(或移动,如果提供)构造函数而不是赋值运算符!
如果没有,默认情况下只提供复制指针,这将导致双重删除,因为 operator+
中的临时对象和目标对象都持有相同的指针。
据我所知,您只是在重新实现 std::vector
已经提供的所有功能!你真的应该考虑使用它而不是尝试(并且失败)重新发明轮子......
顺便说一下:如果您使用 std::vector,根据您目前提供的内容,您可以完全跳过构造函数、析构函数和赋值运算符。默认值将很适合,因为 std::vector
的构造函数/析构函数/赋值运算符随后将被调用,它们可以很好地完成您需要的工作。
关于效率的一些进一步问题和要点(仅供学习,如果您不切换到 std::vector
):
任何分配给new
的资源都必须是delete
d,任何分配给new[]
的资源都必须是delete[]
d!如果你混合(像你一样),未定义的行为!!!
您在创建空数组时引入了内存泄漏:
instructions_ = new string[0];
size_ = 0;
但仅有条件地删除成员(已修复错误删除):
if (size_ != 0)
{
delete[] instructions_;
}
空数组存在,也占内存,任何情况下都需要删除该成员:
//if (size_ != 0)
//{
delete[] instructions_;
//}
更好的是:
instructions_ = nullptr;
size_ = 0;
//if (size_ != 0)
//{
delete[] instructions_;
//}
所以你根本不会为空海龟占用任何内存;你仍然不需要检查,删除空指针是绝对合法的(同时使用 delete
和 delete[]
)...
你绝对应该提供一个移动构造函数/赋值运算符(rule of five):
TurtleProgram::TurtleProgram(TurtleProgram&& that)
: TurtleProgram()
{
*this = std::move(that);
}
TurtleProgram& TurtleProgram::operator=(TurtleProgram&& that)
{
using std::swap;
swap(size_, that.size_);
swap(instructions_, that.instructions_);
return *this;
}
您节省了大量的内存分配和初始化工作...
for (int i = 0; i < this->size_ + that.size_; i++)
{
if (i < this->size_)
{
returnTP.instructions_[i] = this->instructions_[i];
}
else
{
returnTP.instructions_[i] = that.instructions_[i - this->size_];
}
}
制作两个独立的循环:
for (int i = 0; i < this->size_; i++)
{
returnTP.instructions_[i] = this->instructions_[i];
}
for (int i = this->size_; i < this->size_ + that.size_; i++)
{
returnTP.instructions_[i] = that.instructions_[i - this->size_];
}
类似的:
for (int i = 0; i < newSize; i++)
{
if (i < size_)
{
temp[i] = instructions_[i];
}
else
{
temp[i] = "";
}
}
它将得到:
for (int i = 0; i < size_; i++)
{
temp[i] = instructions_[i];
}
嗯,还有第二部分???不必要的,operator new[]
已经调用了任何数组元素的默认构造函数,这无论如何都会创建空字符串......不过有一点开放:对 newSize
的适当处理是小于 size_
。将此留作您的练习。
关于c++ - 为什么我的重载 + 运算符在返回时会产生 "Invalid address specified to RtlValidateHeap"错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49646114/
很难说出这里问的是什么。这个问题是模棱两可的、模糊的、不完整的、过于宽泛的或修辞的,无法以目前的形式得到合理的回答。如需帮助澄清这个问题以便重新打开它,visit the help center .
有谁知道区别吗? 最佳答案 如果您想玩可移植的可执行文件,就没有办法绕过 the specs 的副本。 . 已经有一段时间了,但如果内存正确地为我服务:IT 和 IAT 是相同的,除了 IAT 在解析
我正在尝试在 ec2-instance 上安装 Hadoop-2.6.0。 我下载并安装了 Hadoop。我还设置了环境变量。尝试启动 hdfs 服务时出现以下错误。 [ec2-user@ip-10-
我写了一个示例程序。如果我打印 pa 和 pb 的地址都是不同的。你能告诉我为什么会这样吗? #include using namespace std; class A { int x; }; cla
*&x 是否总是等于 x?如果不是,什么时候不是? &*x 是否总是等于 x?如果不是,什么时候不是? 我的猜测是 (1) 总是正确的,但 (2) 并不总是正确的,因为 x 可能并不总是一个指针,所以
我有一个 Address 类,它是一个非常简单的元数据容器。 (在底部。) 我有一个 Address 对象数组,它不是可选的 - 它肯定存在。我还有一个类维护这些引用的可选列表,如下所示: publi
我在理解 wsdl 中 soap:address 和 http:address 标签之间的区别时遇到了一些问题。它可以互换吗?我可以使用 soap:address 代替 http:address 吗?
关于AT (...) ld 的指令, this source状态: AT ( ldadr ) The expression ldadr that follows the AT keyword spec
我正在使用 Tensorflow 的 C API 在并行模拟中进行推理。因为我想要 AVX 支持,所以我从源代码编译了 Tensorflow。我链接它并使用 wmake 编译所有内容。 现在,如果我开
就像标题一样,我是cxf的新手。只是想知道 soap:address 和发布时在应用程序上下文中的 jaxws:endpoint 中指定的地址有什么区别? 此外,在jaxws:endpoint中,地址
#include #include using namespace std; class myexception: public exception { virtual const char*
C/C++ 应用程序抛出该错误,如何开始调试(比添加打印语句更好的主意)? 最佳答案 第二个地址是不是一个非常小的数字,比如 0x00000001 或 0x00000000?如果是这样,您可能只是忘记
如果我没记错的话,几天前它曾经显示“localhost”。我不确定是什么改变了 server.address().address 返回双冒号 (::) 。我在这里读到,如果它可用,它会返回一个 IPv
我现在正在使用 MPI 练习简单的并行编程。该代码旨在通过随机生成 N*N 矩阵并使用简单的邻域加权平均滤波器来模拟图像处理,而不处理第一行和最后一行和列。我在编译时没有出错,但在运行时出现了一些我无
这个问题在这里已经有了答案: How to retrieve range.address which is longer than 255 character? (2 个回答) 5年前关闭。 觉得很奇
当我尝试启动 Apache2 时收到以下消息: * Restarting web server apache2
我正在阅读一些有关指针和结构的内容,但我就是不明白:微 Controller 的头文件中有这样的内容: #define NVIC_BASE (SCS_BASE + 0x0100) /*ICER[0]
我有 alertmanager 作为 docker 容器在两台不同的主机上运行,并且两者都应该作为集群运行。两台机器都在同一个 vpc 内,并与私有(private) IP 地址通信。 我需要知道
在 Organization schema两者都有属性 address和 location . 什么时候应该使用每一个的真实世界例子? 地点 事件、组织或行动的地点。 地址 项目的物理地址。 最佳答案
我想要具有 FIFO 的服务器-客户端模型和客户端获取目录路径,但我收到错误“读:错误地址”和“写:错误地址”。 客户端 服务器错误:“读取:地址错误” 客户端错误:“写入:地址错误” 最佳答案 您可
我是一名优秀的程序员,十分优秀!