我在字典项目中遇到了一个非常奇怪的问题。基本上我收到访问冲突错误:
0xC0000005:访问冲突读取位置0x00000000
当我尝试在此行中输入单词时,它失败了:
cin >> wrd;
这是我的代码:
void Menu::InsertWord(){
cout << "Please enter number of words: " << endl;
int numberOFwords = InsertNum(); //Function that gets a number of words from the user.
Definition* word = new Definition[numberOFwords];
String wrd;
for (int i = 0; i < numberOFwords; i++){
cout << "Please enter a word: " << endl;
cin >> wrd;
我认为它在"字符串"类中:
#include "String.h"
String::String(char* str) : string(str){
if (!string)
size = 0;
else{
size = Strlen(str);
string = Strcpy(str, size);
}
}
String::String(const String& str){ //copy constractor.
size = Strlen(str.string);
string = Strcpy(str.string, size); //return a pointer to a string.
}
String::~String(){
if (string)
delete[] string;
}
String& String::operator=(const String& other){
if (this != &other && other.string){
size = other.size;
if (string)
delete[] string;
string = new char[Strlen(other.string) + 1];
string = Strcpy(other.string, size);
}
else if (!string && other.string){
size = 0;
delete[] string;
string = NULL;
}
return *this;
}
String& String::operator=(const char* str){
if (str){ //str ISN'T NULL
size = Strlen(str);
delete[] string;
string = new char[size + 1];
Strcpy(string, size);
}
else if (!string && str){
size = 0;
delete[] string;
string = NULL;
}
return *this;
}
bool String::operator==(const String& other) const{
if (size != other.size)
return FALSE;
else{
for (int i = 0; i < size; i++){
if (string[i] != other.string[i])
return FALSE;
}
}
return TRUE;
}
bool String::operator!=(const String& other) const{
return (!(*this == other));
}
istream& operator >>(istream& is, String& other) {
for (int i = 0; i < other.size || i <= WORD_SIZE ; i++){
is >> other.string[i];
if (i == WORD_SIZE)
other.string[WORD_SIZE] = ' ';
}
return is;
}
ostream& operator <<(ostream& os, const String& other) {
for (int i = 0; i < other.size; i++)
os << other.string[i];
return os;
}
String& String::operator -=(const char& chr) {
RemoveChar(chr);
return *this;
}
String& String::operator +=(const char& chr) {
AddChar(chr);
return *this;
}
void String::PrintString(){
size = Strlen(string);
for (int i = 0; i < size; i++){
cout << string[i]; //print the current char.
}
cout << endl;
}
void String::AddChar(const char& chr){
char* temp = new char[size + 2];
for (int i = 0; i < size; i++)
temp[i] = string[i];
temp[size] = chr;
temp[size + 1] = ' ';
delete[] string;
string = temp;
size = size + 1;
}
void String::RemoveChar(const char& chr){
int j, i = 0,counter = 0;
for (i; i < size; i++){
if (chr == string[i])
counter++;
}
char* temp = new char[(size - counter) + 1];
for (i = 0, j = 0; i < size; j++, i++){
if (string[i] != chr)
temp[j] = string[i];
else
j--;
}
temp[size - counter] = ' ';
string = temp;
}
char& String::operator[] (int index){
if (index >= 0 && index < size){
for (index = 0; string[index] != ' '; index++);
return string[index];
}
return string[0];
}
int String::Strlen(const char* str){
if (str){
int counter = 0;
for (; counter < size; counter++);
return counter;
}
return 0;
}
char* String::Strcpy(const char* str, int size){
char* TempString = new char[size + 1];
if (!TempString){ //check if memory allocate.
exit(1);
}
for (int i = 0; i < size; i++){ //copy the string char by char.
TempString[i] = str[i];
if (i + 1 == size) //if it's the end of the string
TempString[size] = ' '; //enter ' ' at the end.
}
return TempString; //return char pointer to the string.
}
您没有显示类字符串的默认构造函数,但我确定如果它存在,它将数据成员字符串设置为 NULL 或 nullptr。
String wrd;
因此,当您使用运算符>>
cin >> wrd;
您正在尝试访问未由类的对象分配的内存。
我也认为运算符循环语句中的这个条件>>
istream& operator >>(istream& is, String& other) {
for (int i = 0; i < other.size || i <= WORD_SIZE ; i++){
^^
是错误的。
似乎至少应该有这样的
istream& operator >>(istream& is, String& other) {
for (int i = 0; i < other.size && i <= WORD_SIZE ; i++){
^^
我也怀疑在这个复制构造函数中
String::String(const String& str){ //copy constractor.
size = Strlen(str.string);
string = Strcpy(str.string, size); //return a pointer to a string.
}
应该有
size = str.size;
而不是
size = Strlen(str.string);
因为 str.string 不是以零结尾的。
目前还完全不清楚函数Strcpy
是如何工作的;它是否动态地为字符串的副本分配内存。
比较构造函数
String::String(char* str) : string(str){
if (!string)
size = 0;
else{
size = Strlen(str);
string = Strcpy(str, size);
}
}
例如,这个赋值运算符(顺便说一下,在任何情况下都是错误的;例如,条件的含义是什么,如果(!string && str){?)
String& String::operator=(const char* str){
if (str){ //str ISN'T NULL
size = Strlen(str);
delete[] string;
string = new char[size + 1];
Strcpy(string, size);
}
else if (!string && str){
size = 0;
delete[] string;
string = NULL;
}
return *this;
}
在构造器中,您不显式分配内存,而在赋值运算符中显式分配内存。所以它看起来至少很奇怪:)