Вызывающий push_back в векторе<int> к ошибке сегментирования в том, что кажется простой операцией
-
21-09-2019 - |
Вопрос
Я работаю над программой для Проект Эйлер чтобы сложить все цифры 2 ^ 1000.До сих пор мне удавалось отслеживать ошибки сегментации программы, когда она достигает примерно 5 цифр и пытается вставить единицу в вектор в строке 61 в функции carry().
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class MegaNumber
{
vector<int> data; //carries an array of numbers under ten, would be char but for simplicity's sake
void multiplyAssign(int operand, int index); //the recursive function called by the *= operator
void carry(int index);//if one of the data entries becomes more than ten call this function
public:
void printNumber(); //does what it says on the can
void operator*=(MegaNumber operand);
void operator*=(int operand);
void operator+=(int operand);
MegaNumber(string);
unsigned long int AddAllDigits();//returns the value of all of the digits summed
};
MegaNumber::MegaNumber(string operand)
{
for(int i= operand.size()-1; i>=0;i--) //run it into the memory smallest digit first
{
data.push_back(operand[i]-48); //converts a text char to an int
}
}
void MegaNumber::printNumber()
{
int temp = data.size();
for(unsigned int i=(temp); i>0;--i)
{
cout << (int)data[i-1];
}
}
void MegaNumber::operator*=(int operand)
{
if(operand > 9)
{
cout << "function does not yet deal with large ints than 9";
}
else multiplyAssign(operand, 0);
}
void MegaNumber::multiplyAssign(int operand, int index)
{
data[index] *=operand;
if(index<data.size()) multiplyAssign(operand, index+1);
if(data[index] > 9) carry(index);
}
void MegaNumber::carry(int index)
{
int temp = (data[index] / 10); //calculate the amount to carry
if(data.size()==index+1)
{
data.push_back(temp);//if there is no upper digit push it onto the stack
}
else
{
data[index+1]+=temp; //else add it to the next digit
if(data[index+1]>9) carry(index+1); //rinse and repeat
}
data[index]-=temp*10; //remove what's been carried
}
unsigned long int MegaNumber::AddAllDigits() //does what it says on the can
{
unsigned long int Dagger = 0;
for(int i=0; i<data.size();i++) Dagger+=data[i];
return Dagger;
}
int main()
{
MegaNumber A("2");
A.printNumber();
cout << "\n";
for(unsigned int i=0; i<20; i++) A*=2;
A.printNumber();
cout << "\n";
cout << A.AddAllDigits() << "\n";
cout << "Hello world!" << endl;
return 0;
}
Что может быть причиной этого?
Решение
void MegaNumber::multiplyAssign(int operand, int index)
{
data[index] *=operand;
if(index<data.size()) multiplyAssign(operand, index+1);
if(data[index] > 9) carry(index);
}
index
основано на 0, в то время как data.size()
основан ли 1, так сказать, на значении data.size()
возвращает число на 1, большее, чем наибольшее допустимое index
.Так что, похоже, ваше намерение было
if( index < data.size() - 1) multiplyAssign(operand, index+1);
Тогда это работает.
P.S.разбейте ваш код на строки, тот, кто должен поддерживать ваш код, будет благодарен вам за это:
if (index < data.size() - 1)
{
multiplyAssign(operand, index + 1);
}
Другие советы
Вы используете data[index] перед проверкой, является ли это допустимым индексом, в multiplyAssign
:
data[index] *= operand;
if(index<data.size()) multiplyAssign(operand, index+1);
Также используйте '0'
вместо того , чтобы 48
.Это проще, понятнее и менее подвержено ошибкам.
Я думаю, что проблема может быть здесь: data[index+1]+=temp;
Этот элемент не мог бы существовать, если index
параметр eq.до размера data
.
Итак, мои рекомендации:
- Используйте итераторы для доступа
std::vector
- Проверьте условия привязки, если вы не используете итераторы