我已经创建了一个类,它为通过析构函数删除的数组使用已分配的内存。出于某种原因,我使用new关键字来创建指向此类变量的指针,当我尝试删除它时,程序崩溃并出现堆损坏错误。
UPDATE `wp_postmeta`
SET `meta_value` = REPLACE(`meta_value`, 'jwp-test/' , '')
WHERE `meta_value` LIKE '%jwp-test/%'
蝴蝶鱼类基于鱼类。
int main() {
Butterflyfish *tad
= new Butterflyfish(3, "tad");
tad->printMemory();
tad->remember('a');
tad->remember('x');
tad->remember('a');
tad->remember('b');
tad->remember('c');
tad->remember('a');
tad->remember('d');
tad->printMemory();
tad->forget();
tad->printMemory();
delete tad; //causes crash
return 0;
}
鱼类在测试时没有错误,所以只有你想要使用它才能。这是蝴蝶鱼类。
Fish::Fish(int capacity, std::string name)
{
if (capacity < 0)
{
capacity = 3;
}
this->m_memory = new char[capacity];
for (int i = 0; i < capacity; i++)
{
this->m_memory[i] = '.';
}
this->m_capa = capacity;
this->m_used = 0;
this->m_name = name;
this->m_full = false;
}
Fish::Fish(const Fish& other)
{
this->m_name = other.m_name;
this->m_capa = other.m_capa;
this->m_used = other.m_used;
this->m_full = other.m_full;
this->m_memory = new char[m_capa];
for (int i = 0; i < this->m_capa; i++)
{
this->m_memory[i] = other.m_memory[i];
}
}
Fish::~Fish()
{
delete[] m_memory;
}
Fish& Fish::operator=(const Fish& other)
{
// TODO: insert return statement here
if ( this == &other )
{
return *this;
}
this->m_name = other.m_name;
this->m_capa = other.m_capa;
this->m_used = other.m_used;
this->m_full = other.m_full;
this->m_memory = new char[m_capa];
for (int i = 0; i < this->m_capa; i++)
{
this->m_memory[i] = other.m_memory[i];
}
return *this;
}
void Fish::remember(char c)
{
if (m_used != (m_capa - 1))
{
for (int i = m_used; i >= 0; i--)
{
this->m_memory[i + 1] = this->m_memory[i];
}
this->m_memory[0] = c;
this->m_used++;
}
else if (this->m_used == (this->m_capa - 1))
{
if (this->m_full)
{
for (int i = m_used; i > 0; i--)
{
this->m_memory[m_used] = this->m_memory[m_used - 1];
}
this->m_memory[0] = c;
}
else
{
for (int i = m_used; i > 0; i--)
{
this->m_memory[i] = this->m_memory[i - 1];
}
this->m_memory[0] = c;
this->m_used = this->m_capa;
this->m_full = true;
}
}
}
void Fish::forget()
{
for (int i = 0; i < m_capa; i++)
{
this->m_memory[i] = '.';
}
this->m_used = 0;
this->m_full = false;
}
void Fish::printMemory() const
{
std::cout << "{ ";
for (int i = 0; i < m_capa; i++)
{
std::cout << this->m_memory[i] << " ";
}
std::cout << '}' << std::endl;
}
std::string Fish::getName()
{
return this->m_name;
}
const char* Fish::getMemory() const
{
return m_memory;
}
int Fish::getAmount() const
{
return this->m_used;
}
int Fish::getCapacity() const
{
return this->m_capa;
}
鱼可以记住预定容量的琴弦。蝴蝶鱼类具有特殊的技能,它可以记住它看到的每一个字母以及看到它们的次数。当第二个内存已满时,它的第二个内存容量可以使其容量翻倍。
这些是类声明。
Butterflyfish::Butterflyfish(int capacity, std::string name) : Fish(capacity, name)
{
m_extended = new OBBY[capacity];
m_exUsed = 0;
m_exCapa = capacity;
}
Butterflyfish::Butterflyfish(const Butterflyfish &other) : Fish(other)
{
this->m_exCapa = other.m_exCapa;
this->m_exUsed = other.m_exUsed;
this->m_extended = new OBBY[this->m_exCapa];
for (int i = 0; i < m_exUsed; i++)
{
this->m_extended[i].letter = other.m_extended[i].letter;
this->m_extended[i].times = other.m_extended[i].times;
}
}
Butterflyfish& Butterflyfish::operator=(const Butterflyfish &other)
{
if (this == &other)
{
return *this;
}
else
{
Fish::operator=(other);
this->m_exCapa = other.m_exCapa;
this->m_exUsed = other.m_exUsed;
this->m_extended = new OBBY[this->m_exCapa];
for (int i = 0; i < m_exUsed; i++)
{
this->m_extended[i].letter = other.m_extended[i].letter;
this->m_extended[i].times = other.m_extended[i].times;
}
return *this;
}
}
Butterflyfish::~Butterflyfish()
{
delete[] m_extended;
}
void Butterflyfish::remember(char c)
{
Fish::remember(c);
tolower(c);
if (m_exUsed == m_exCapa)
{
OBBY* temp = new OBBY[m_exCapa];
for (int i = 0; i < m_exCapa; i++)
{
temp[i].letter = m_extended[i].letter;
temp[i].times = m_extended[i].times;
}
delete[] m_extended;
m_extended = new OBBY[m_exCapa * 2];
for (int j = 0; j < m_exUsed; j++)
{
m_extended[j].letter = temp[j].letter;
m_extended[j].times = temp[j].times;
}
m_exCapa *= 2;
delete[] temp;
}
if (m_exUsed == 0)
{
m_extended[0].letter = c;
m_extended[0].times = 1;
m_exUsed = 1;
}
else
{
bool match = false;
for (int i = 0; i < m_exUsed; i++)
{
if ( m_extended[i].letter == c )
{
m_extended[i].times += 1;
match = true;
break;
}
}
if (match == false)
{
m_extended[m_exUsed].letter = c;
m_extended[m_exUsed].times += 1;
m_exUsed += 1;
}
}
}
void Butterflyfish::printMemory() const
{
Fish::printMemory();
std::cout << "I'm Obnoxious" << std::endl;
if (m_exUsed == 0)
{
return;
}
std::cout << "I've Seen" << "\n\t";
for (int i = 0; i < m_exUsed; i++)
{
if (i == (m_exUsed - 1))
{
std::cout << "and " << m_extended[i].letter << " " << m_extended[i].times << " times\n";
}
else
{
std::cout << m_extended[i].letter << " " << m_extended[i].times << " times\n\t";
}
}
}
答案 0 :(得分:2)
让我们仔细看看这个功能的部分
void Fish::remember(char c)
{
if (m_used != (m_capa - 1))
{
// ...
}
else if (this->m_used == (this->m_capa - 1))
{
if (this->m_full)
{
// ...
}
else
{
// ...
this->m_used = this->m_capa;
// ...
}
}
}
直到m_used == m_capa - 1
。
问题在于,当发生这种情况时,您将设置m_used = m_capa
。在下一个电话中m_used != m_capa - 1
true ,您将超出已分配的内存范围。
从
更改初始条件if (m_used != (m_capa - 1))
到
if (m_used <= (m_capa - 1))
不要else if (...)
,只是简单else
。
请注意,如果您学会了如何使用调试器逐行遍历代码,那将非常明显。