![](/img/trans.png)
[英]BLOCK_TYPE_IS_VALID(pHead->nBlockUse) occurs on main return
[英]_BLOCK_TYPE_IS_VALID(pHead->nBlockUse) after “return 0”
我正在編寫一個程序,其中必須編寫自己的字符串類和一個葯水類。 我知道這個運行時錯誤通常是由於程序刪除了未分配的內容而引起的,但是它在main中的“ return 0”之后發生。 我已經逐行調試它,並嘗試了一些嘗試來消除運行時錯誤,但實際上沒有任何效果。 有沒有人可以幫助我解決這個問題?
這是我的代碼:
//Main
#include "Potion.h"
#include <iostream>
using std::cout;
using std::endl;
void TotalCost( Potion ArrayofPotions[5] )
{
String Currency[4] = {"Platinum", "Gold", "Silver" ,"Copper"};
int TotalCost[4] = {0, 0, 0, 0};
int Cost[4] = {0, 0, 0, 0};
for (short i = 0; i < 5; i++)
{
for (short k = 0; k < 4; k++)
{
Cost[k] = ArrayofPotions[i].ConvertCost(k);
TotalCost[k] += Cost[k];
if ( i != 0 )
TotalCost[k] = ArrayofPotions[k].CalculateCost(TotalCost[k - 1], TotalCost[k]);
}
}
cout << "\nTotal cost for all potions: ";
for (short i = 0; i < 4; i++)
{
cout << TotalCost[i] << ' ';
Currency[i].Display();
}
}
int main()
{
Potion Haggling("Potion of Haggling", "You haggle for 10% better prices for 30 seconds",
"Weak", "0.80.0.4.");
Potion Strength("Draught of Strength", "You can carry 20% more for 300 seconds",
"Low", "2.60.5.1.");
Potion Health("Solution of Health", "You are 30% tougher for 60 seconds",
"Mild", "2.20.5.1.");
Potion Stealth("Philter of Stealth", "You are 40% harder to detect for 60 seconds",
"Moderate", "0.90.5.1.");
Potion Waterbreathing("Elixir of Waterbreathing", "You can breathe underwater for 60 seconds",
"Strong", "2.10.5.0.");
Potion ArrayOfPotions[5] = {Haggling, Strength, Health, Stealth, Waterbreathing};
for (short i = 0; i < 5; i++)
ArrayOfPotions[i].DisplayPotions();
TotalCost(ArrayOfPotions);
system("pause");
return 0;
}
//String class
class String
{
public:
String() : m_str(nullptr)
{ }
String(char chr) : m_str(nullptr)
{
m_str = new char;
*m_str = ch;
}
String(char * str)
{
if (str != nullptr)
{
m_str = new char[strlen(str) + 1];
strcpy(m_str, str);
}
}
String(const String & copy) : m_str(copy.m_str)
{ }
String& operator=(const String & rhs)
{
if ( this != &rhs )
{
delete [] m_str;
m_str = new char[strlen(rhs.m_str) + 1];
strcpy(m_str, rhs.m_str);
}
return *this;
}
~String()
{
delete [] m_str;
}
void Display() const
{
cout << m_str;
}
char * GetStr() const
{
return m_str;
}
String Upper()
{
char * check = this->m_str;
for (unsigned short i = 0; i < strlen( this->m_str ); i++, check++)
{
if ( *check > 96 && *check < 123 )
{
*check -= 32;
}
else
m_str = this->m_str;
}
return m_str;
}
private:
char * m_str;
};
//Potion class
#include "String.h"
class Potion
{
public:
Potion() : m_name(nullptr), m_description(nullptr), m_potency(nullptr),
m_cost(nullptr)
{ }
Potion(String name, String description, String potency, String cost)
{
m_name = name;
m_description = description;
m_potency = potency.Upper();
m_cost = cost;
}
Potion(const Potion & copy) : m_name(copy.m_name), m_description(copy.m_description),
m_potency(copy.m_potency), m_cost(copy.m_cost)
{ }
int ConvertCost(int index)
{
int cost = 0;
char * new_cost = m_cost.GetStr();
char * temp_string = new char[strlen( new_cost ) + 1];
strcpy(temp_string, new_cost);
char * temp = strtok( temp_string, "." );
for (short k = 0; k != index; k++)
temp = strtok( NULL, "." );
cost = atoi( temp );
delete [] temp_string;
return cost;
}
int CalculateCost(int & cost1, int cost2)
{
if (cost > 99)
{
cost1++;
cost2 -= 100;
}
return cost2;
}
void DisplayPotions()
{
String Currency[4] = {"Platinum", "Gold", "Silver" ,"Copper"};
int cost = 0;
m_name.Display();
m_description.Display();
m_potency.Display();
for (short i = 0; i < 4; i++)
{
cost = ConvertCost(i);
if (cost != 0)
{
cout << ConvertCost(i) << ' ';
Currency[i].Display();
}
}
}
private:
String m_name;
String m_description;
String m_potency;
String m_cost;
};
抱歉,這確實很長,我省略了一些輸出格式,但是我確實需要一些幫助。
PS我的教授希望我們將成本從字符串轉換為整數,並且必須以“ 0.0.0.0”格式輸入。 這就是為什么它是這樣寫的。
您的賦值運算符已損壞,因為它從右側復制了指針。
您需要遵循與復制構造函數相同的過程。
順便說一句,復制構造函數也被破壞了,因為如果rhs
為空,它將失敗。
(在空字符串的表示中使用空字符串是一個更安全的想法(即使用""
代替nullptr
)。
它使您免於進行大量的null檢查。)
此構造函數也已損壞:
String(char * str)
{
if (str != nullptr)
{
m_str = new char[strlen(str) + 1];
strcpy(m_str, str);
}
}
因為如果將它傳遞給nullptr
,它m_str
初始化-並且您需要執行很多操作。
此構造函數也已損壞:
String(char chr) : m_str(nullptr)
{
m_str = new char;
*m_str = ch;
}
因為它不會構造零結尾的字符串。
你需要
m_str = new char[2];
m_str[0] = ch;
m_str[1] = 0;
正如其他人所述,您的構造函數已損壞。 除此之外,賦值運算符也以微妙的方式被破壞。
解決此問題的最簡單方法是將大多數賦值運算符代碼移至復制構造函數。
String(const String & copy) : m_str(new char[strlen(copy.m_str)+1])
{
strcpy(m_str, copy.m_str);
}
對於您的賦值運算符,缺點是它會在調用new[]
之前刪除內存。 如果new[]
拋出異常會怎樣? 您已經破壞了舊數據,並且無法恢復數據。
而不是您如何編寫賦值運算符,而是一種更好的方法:
#include <algorithm>
//...
String& operator=(String rhs)
{
std::swap(rhs.m_str, m_str);
return *this;
}
那很簡單,而且有效。 它需要一個工作副本構造函數和String
工作析構函數。 由於您提供了這兩個功能,編寫賦值運算符變得很簡單。
請參閱copy/swap idiom
: 什么是復制和交換慣用語?
這也可以確保,如果new[]
引發異常,則不會破壞您的原始字符串。 std::swap
僅交換兩個項目-如果您不能使用std::swap
則編寫自己的函數來交換指針,因為實現起來應該非常簡單。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.