在向量中引起push_back;对看似简单的操作进行分段故障

发布于 2024-08-12 08:29:11 字数 2651 浏览 12 评论 0原文

我正在为 Project Euler 编写一个程序,将 2^1000 的所有数字相加。到目前为止,我已经能够在程序达到大约 5 位数字时跟踪程序分段错误,并尝试将 1 推入函数进位()中第 61 行的向量上。

#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;
}

可能是什么原因造成的?

I'm working on a program for Project Euler to add all the digits of 2^1000. So far I've been able to track the program segmentation faults when it reaches around 5 digits and tries to push a one onto the vector at line 61 in the function 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;
}

What may be causing this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

浪漫之都 2024-08-19 08:29:11

您可以在 multiplyAssign 中使用 data[index],然后再检查它是否是有效索引:

data[index] *= operand;
if(index<data.size()) multiplyAssign(operand, index+1);

同时使用 '0' 而不是 48。这更容易、更清晰并且更不易出现错误。

You use data[index] before checking if it's a valid index, in multiplyAssign:

data[index] *= operand;
if(index<data.size()) multiplyAssign(operand, index+1);

Also use '0' instead of 48. This is easier, clearer, and less bug-prone.

久光 2024-08-19 08:29:11
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 大于最大的有效索引
所以看起来你的意图是

if( index < data.size() - 1) multiplyAssign(operand, index+1);

那么它就有效了。
PS 将你的代码分成几行,任何维护你的代码的人都会为此感谢你:

if (index < data.size() - 1) 
{
    multiplyAssign(operand, index + 1);
}
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 is 0 based, while data.size() is 1 based so to say, meaning data.size() returns number 1 greater than the largest valid index.
So looks like you intention was

if( index < data.size() - 1) multiplyAssign(operand, index+1);

Then it works.
P.S. break your code into lines, whoever has to maintain your code will thank you for that:

if (index < data.size() - 1) 
{
    multiplyAssign(operand, index + 1);
}
苦笑流年记忆 2024-08-19 08:29:11

我认为问题可能出在这里: data[index+1]+=temp;

如果 index 参数 eq 则该元素不能存在。到数据的大小。

所以,我的建议是:

  • 使用迭代器访问 std::vector
  • 如果不使用迭代器,请检查绑定条件

I think the problem could be here: data[index+1]+=temp;

This element could not be exist if index parameter eq. to size of data.

So, my recommendations:

  • Use Iterators to access std::vector
  • Check bound conditions if you do not use Iterators
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文