C++在while循环后加一行代码报错
C++ adding one line of code after while loop causes an error
我已尽力寻找能够解决我的具体问题的答案,但不幸的是,我找不到满足我需求的答案。
我正在用 c++ 为我编写的语言编写汇编程序。编写汇编程序涉及两个 classes,它们一直在导致问题,这些问题确实很难调试。我的调试技术已经转移到添加和删除输出流命令,如
std::cout << "TEST";
这最终会破坏或修复程序。我使用的 IDE 是 Xcode.
我正在处理的两个 class 是一个 LinkedList class 和一个 SymbolTable class,我将它们用作符号解析的散列 table .
LinkedList.h
#include <iostream>
using namespace std;
struct Node{
string data;
int address;
Node* next = nullptr;
};
class LinkedList{
private:
Node* main_ptr;
int length;
public:
LinkedList();
void insertNode(string, int);
void deleteNode(string);
void displayList();
bool contains(string, int* = nullptr);
int getLength();
~LinkedList();
};
LinkedList.cpp
#include "LinkedList.h"
LinkedList::LinkedList(){
main_ptr = nullptr;
length = 0;
}
void LinkedList::insertNode(string data, int address){
Node* newNode = new Node;
newNode->data = data;
newNode->address = address;
if (!main_ptr){
main_ptr = newNode;
} else {
newNode->next = main_ptr;
main_ptr = newNode;
}
length++;
}
void LinkedList::deleteNode(string data){
if (main_ptr){
int current_length = length;
if (main_ptr->data == data){
main_ptr = main_ptr->next;
return;
}
Node* q = main_ptr;
Node* p = q;
q = q->next;
while (q){
if (q->data == data){
p->next = q->next;
length--;
return;
}
p = q;
q = q->next;
}
if (current_length == length) cout << "Node was not found" << endl;
} else {
cout << "List is empty, cannot delete node!" << endl;
}
}
void LinkedList::displayList(){
if (!main_ptr){
cout << "List is empty!\n";
} else {
Node* temp = main_ptr;
while (temp){
cout << temp->data;
temp = temp->next;
}
cout << endl;
}
}
bool LinkedList::contains(string data, int* address){
if (main_ptr == nullptr) return false;
else {
Node* temp = main_ptr;
while(temp != nullptr){
if (temp->data == data) {
address = &(temp->address);
return true;
}
temp = temp->next;
}
return false;
}
}
int LinkedList::getLength(){
return length;
}
LinkedList::~LinkedList(){
if (main_ptr){
Node* q = main_ptr;
Node* p = q;
while (q){
q = q->next;
delete p;
p = q;
}
}
}
SymbolTable.h
#include "LinkedList.h"
#include <iostream>
class SymbolTable{
private:
LinkedList table[701];
public:
SymbolTable();
void addEntry(string, int);
void printTable();
bool contains(string, int*);
int convertName(string);
};
SymbolTable.cpp
#include "SymbolTable.h"
SymbolTable::SymbolTable(){
}
void SymbolTable::addEntry(string name, int memory){
int address = convertName(name);
table[address].insertNode(name, memory);
}
void SymbolTable::printTable(){
for (int i = 0; i < 701; i++)
table[i].displayList();
}
bool SymbolTable::contains(string name, int* memory){
return table[convertName(name)].contains(name, memory);
}
int SymbolTable::convertName(string name){
int aggregate = 1;
const char* c_name = name.c_str();
for (int i = 0; i < name.length(); i++){
aggregate *= (int)c_name[i];
}
return aggregate%701;
}
现在是我的实际问题。以下是主要功能:
#include "Parser.h"
#include "SymbolTable.h"
using namespace std;
int main(int argc, const char * argv[]) {
ifstream inputFile;
ofstream outputFile;
inputFile.open("/Users/Azaldin/Desktop/nand2tetris/projects/06/max/Max.asm");
outputFile.open("/Users/Azaldin/Desktop/nand2tetris/projects/06/max/Max.hack");
Parser a(inputFile);
SymbolTable s;
int commandType = -1;
string command;
int a_position = 16;
int currentLine = 0;
while (a.hasMoreCommands()){
a.advance();
commandType = a.commandType();
command = a.symbol();
if (commandType == 0){
if (!s.contains(command, nullptr)){
s.addEntry(command, a_position);
a_position++;
}
}
if (commandType == 2){
//cout << command << endl;
if (!s.contains(command, nullptr)){
s.addEntry(command, currentLine);
//cout << command << endl;
}
}
currentLine++;
}
string x; //<<<<<<<<<< ADDING THIS LINE BREAKS THE PROGRAM
cout << "Hi";
inputFile.close();
outputFile.close();
return 0;
}
在主函数中添加上面指向的行后,程序中断。
经调试,主线程出现如下问题:
Thread 1:EXC_BAD_ACCESS (code = 1, address=0x25fbfef80)
导致此问题的命令链:
if (!s.contains(command, nullptr)){
来自主函数
return table[convertName(name)].contains(name, memory);
来自 SymbolTable.cpp "contains" 函数
if (temp->data == data) {
来自 LinkedList.cpp "contains" 函数
链命令的其余部分指向字符串 class == 运算符,然后指向左侧的 .size() 函数。
谢谢!
PaulMcKenzie 的以下评论帮助解决了问题:
Also, aggregate *= (int)c_name[i]; -- there is no guarantee that this
will be a positive number, since a character may be signed, thus
giving you values of -1 and below. Thus your return of return
aggregate%701; isn't going to return what you expected (a number >=
0).
事实证明,传递给 SymbolTable class 中的 convertName 函数的参数之一导致程序损坏了内存。我添加了一个 if 语句来解决问题。
我已尽力寻找能够解决我的具体问题的答案,但不幸的是,我找不到满足我需求的答案。
我正在用 c++ 为我编写的语言编写汇编程序。编写汇编程序涉及两个 classes,它们一直在导致问题,这些问题确实很难调试。我的调试技术已经转移到添加和删除输出流命令,如
std::cout << "TEST";
这最终会破坏或修复程序。我使用的 IDE 是 Xcode.
我正在处理的两个 class 是一个 LinkedList class 和一个 SymbolTable class,我将它们用作符号解析的散列 table .
LinkedList.h
#include <iostream>
using namespace std;
struct Node{
string data;
int address;
Node* next = nullptr;
};
class LinkedList{
private:
Node* main_ptr;
int length;
public:
LinkedList();
void insertNode(string, int);
void deleteNode(string);
void displayList();
bool contains(string, int* = nullptr);
int getLength();
~LinkedList();
};
LinkedList.cpp
#include "LinkedList.h"
LinkedList::LinkedList(){
main_ptr = nullptr;
length = 0;
}
void LinkedList::insertNode(string data, int address){
Node* newNode = new Node;
newNode->data = data;
newNode->address = address;
if (!main_ptr){
main_ptr = newNode;
} else {
newNode->next = main_ptr;
main_ptr = newNode;
}
length++;
}
void LinkedList::deleteNode(string data){
if (main_ptr){
int current_length = length;
if (main_ptr->data == data){
main_ptr = main_ptr->next;
return;
}
Node* q = main_ptr;
Node* p = q;
q = q->next;
while (q){
if (q->data == data){
p->next = q->next;
length--;
return;
}
p = q;
q = q->next;
}
if (current_length == length) cout << "Node was not found" << endl;
} else {
cout << "List is empty, cannot delete node!" << endl;
}
}
void LinkedList::displayList(){
if (!main_ptr){
cout << "List is empty!\n";
} else {
Node* temp = main_ptr;
while (temp){
cout << temp->data;
temp = temp->next;
}
cout << endl;
}
}
bool LinkedList::contains(string data, int* address){
if (main_ptr == nullptr) return false;
else {
Node* temp = main_ptr;
while(temp != nullptr){
if (temp->data == data) {
address = &(temp->address);
return true;
}
temp = temp->next;
}
return false;
}
}
int LinkedList::getLength(){
return length;
}
LinkedList::~LinkedList(){
if (main_ptr){
Node* q = main_ptr;
Node* p = q;
while (q){
q = q->next;
delete p;
p = q;
}
}
}
SymbolTable.h
#include "LinkedList.h"
#include <iostream>
class SymbolTable{
private:
LinkedList table[701];
public:
SymbolTable();
void addEntry(string, int);
void printTable();
bool contains(string, int*);
int convertName(string);
};
SymbolTable.cpp
#include "SymbolTable.h"
SymbolTable::SymbolTable(){
}
void SymbolTable::addEntry(string name, int memory){
int address = convertName(name);
table[address].insertNode(name, memory);
}
void SymbolTable::printTable(){
for (int i = 0; i < 701; i++)
table[i].displayList();
}
bool SymbolTable::contains(string name, int* memory){
return table[convertName(name)].contains(name, memory);
}
int SymbolTable::convertName(string name){
int aggregate = 1;
const char* c_name = name.c_str();
for (int i = 0; i < name.length(); i++){
aggregate *= (int)c_name[i];
}
return aggregate%701;
}
现在是我的实际问题。以下是主要功能:
#include "Parser.h"
#include "SymbolTable.h"
using namespace std;
int main(int argc, const char * argv[]) {
ifstream inputFile;
ofstream outputFile;
inputFile.open("/Users/Azaldin/Desktop/nand2tetris/projects/06/max/Max.asm");
outputFile.open("/Users/Azaldin/Desktop/nand2tetris/projects/06/max/Max.hack");
Parser a(inputFile);
SymbolTable s;
int commandType = -1;
string command;
int a_position = 16;
int currentLine = 0;
while (a.hasMoreCommands()){
a.advance();
commandType = a.commandType();
command = a.symbol();
if (commandType == 0){
if (!s.contains(command, nullptr)){
s.addEntry(command, a_position);
a_position++;
}
}
if (commandType == 2){
//cout << command << endl;
if (!s.contains(command, nullptr)){
s.addEntry(command, currentLine);
//cout << command << endl;
}
}
currentLine++;
}
string x; //<<<<<<<<<< ADDING THIS LINE BREAKS THE PROGRAM
cout << "Hi";
inputFile.close();
outputFile.close();
return 0;
}
在主函数中添加上面指向的行后,程序中断。 经调试,主线程出现如下问题:
Thread 1:EXC_BAD_ACCESS (code = 1, address=0x25fbfef80)
导致此问题的命令链:
if (!s.contains(command, nullptr)){
来自主函数return table[convertName(name)].contains(name, memory);
来自 SymbolTable.cpp "contains" 函数if (temp->data == data) {
来自 LinkedList.cpp "contains" 函数
链命令的其余部分指向字符串 class == 运算符,然后指向左侧的 .size() 函数。
谢谢!
PaulMcKenzie 的以下评论帮助解决了问题:
Also, aggregate *= (int)c_name[i]; -- there is no guarantee that this will be a positive number, since a character may be signed, thus giving you values of -1 and below. Thus your return of return aggregate%701; isn't going to return what you expected (a number >= 0).
事实证明,传递给 SymbolTable class 中的 convertName 函数的参数之一导致程序损坏了内存。我添加了一个 if 语句来解决问题。