C++ 我不能让我的析构函数在我的代码中工作
就像我在标题中说的,我不能让析构函数工作。原因是,在这个程序中,我需要使用带有负索引的int数组:在运行时,我总是随机地获得这个错误:微软C++异常:STD::BADYOLL在内存位置0x9009DF130。 以下是我认为与错误有关的代码:C++ 我不能让我的析构函数在我的代码中工作,c++,C++,就像我在标题中说的,我不能让析构函数工作。原因是,在这个程序中,我需要使用带有负索引的int数组:在运行时,我总是随机地获得这个错误:微软C++异常:STD::BADYOLL在内存位置0x9009DF130。 以下是我认为与错误有关的代码: private: int* run; IntArray::IntArray(int a, int b) { int c = b-a; run = new int [c] + a; //This is how i give it a negat
private: int* run;
IntArray::IntArray(int a, int b)
{
int c = b-a;
run = new int [c] + a; //This is how i give it a negative indicie
h = b;
l = a;
}
IntArray::~IntArray()
{
delete[]run;
}
string IntArray::setName(string sp)
{
s = sp;
return s;
}
void runSim() {
IntArray b(-4, 6);
for (int i = b.low(); i <= b.high(); i++)
// low is the lowes bound high is the highest
b[i] = i * 10;
b.setName("b"); //this is where it breaks and gives me that error
wait();
}
private:int*run;
IntArray::IntArray(inta,intb)
{
int c=b-a;
run=new int[c]+a;//我就是这样给它一个负号的
h=b;
l=a;
}
IntArray::~IntArray()
{
删除[]运行;
}
字符串IntArray::setName(字符串sp)
{
s=sp;
返回s;
}
void runSim(){
内排b(-4,6);
对于(int i=b.low();i您有一个简单的错误:
不要将值传递给delete[]
您没有从new[]
获得的值(或已经传递过一次)
您需要撤消指针算法以获得正确的指针
另外,请注意,如果使用指针算法创建指向数组外部的指针,则存在未定义的行为
如果这不是您的实际代码,请小心尝试分配少于1个元素。因为您在新建它时将a
(又称l
)添加到运行中,所以在删除它时必须减去:
delete[] (run - l);
不是故意的,但这是很糟糕的代码
首先,如果b-a
返回的数字小于0
,您可能会得到std::bad_alloc
,如果a
c
您将进入未定义的行为[可怕]区域,如果您尝试使用指针,可能会得到segfault
如果您试图delete[]
指向new int[c]+a
的指针,您几乎肯定会遇到错误
在尝试delete[]之前,您需要执行run-=a
it,实现将在给定指针之前的空间中存储有关任何new
或malloc
的信息,以便在delete
或free
内存时,它只需在指针后面运行并获取它所需的任何信息,或者将信息存储在一个隐藏数组中的某个位置它是由指针的数字表示来索引的。但可能是第一种。无论哪种方式,你都在做你正在做的事情。唯一正确的方法是在你的类上定义一个自定义的操作符[]
。你的代码有很多错误:
您可以访问low
和high
,即high-low+1
元素。但您只分配high-low
如果p=newint[high-low+1]
,那么run=p+low;
和run[low]
意味着*(p+low+low)
。这是崩溃的直接原因——您在数组之外编写,破坏了内部元数据,这使得下一个用户(字符串的赋值操作符)的动态分配失败
当计算run
时,应该减去low
,这样run[low]
将给出p[0]
,第一个分配的元素。但是这可能会计算数组外的指针(当low
为正时),这是未定义的行为
您传递一个指向delete[]
的指针,该指针不是来自数组new
。您需要传递p
,而不是run
,以delete[]
<> LI>在异常安全方面没有尝试。C++中动态内存的管理是一个高级话题,证据表明您还没有准备好。所以使用现有的智能指针管理内存。
这里有一个更好的版本:
#include <memory>
template<typename T>
class ArbBoundArray
{
int low;
std::unique_ptr<T[]> base;
public:
ArbBoundArray(int l, int h) : low(l), base(new T[h-l+1]) {}
T& operator[](int o) { return base[o-low]; }
const T& operator[](int o) const { return base[o-low]; }
};
#包括
样板
类ArbBoundArray
{
int低;
std::唯一的ptr基;
公众:
arboundarray(intl,inth):低(l),基(新的T[h-l+1]){}
T&运算符[](int-o){返回基[o-low];}
常量T&运算符[](int-o)常量{返回基[o-low];}
};
就是这样。更少的代码,适用于任何类型,不仅仅是int
,而且是异常安全的
您可以在基本概念的基础上添加您的特殊需求,如名称或其他任何内容。这仅适用于他给出的情况,如果a
和b
的值不同会怎么样?@CoffeeandCode您是否混淆了1
和l
?@CoffeeandCode是l
(变量名称)不是一个1
。这就是为什么你永远不应该命名变量l
。我的坏哈哈哈,这就是我想的,我很困惑,因为它也不等于1:L@CoffeeandCode:是的,我考虑在这里写一篇关于单字符变量名的长篇大论,但决定不写。我很高兴不仅仅是我发现了l
令人困惑!您能否详细说明一下“不要传递一个值来删除[]您没有从new[](或已经传递过一次)。”非常简单,您可以从new t[size]
获得一个指针值。您必须将相同的指针值传递给delete[]p
,而不是一些不同的(尽管相关)因此,如果您仅将其安全设置为p+3
,则必须撤消该添加,因此您有(p+3)-3
.TY作为反馈,是的,我有一个重载[]运算符和其他运算符一起,但没有导致错误。这仍然与内存有关,我不知道为什么我的完整代码会太长post@jogojapan:是的,我想是的,但是我的笔记本电脑还没有一个正常工作的突触连接,所以我不得不按一下键。真糟糕。@Tony.v:你在那之后还有记忆问题吗修复我指出的所有问题?您当前看到的错误最可能的直接原因是您在for循环中超出了界限。上限定义为I您的成员run
不包含指向您使用new
创建的数组的指针@Galik run是一个私有点