我得到了#34; Segmentation Fault"不使用指针。怎么了?

时间:2014-07-14 01:05:05

标签: c++ recursion segmentation-fault

已解决:段错由无限(好,不是实际无限)递归引起。当我忘记考虑案例uint pow(uint a, uint b)时,无限递归发生在我的b = 0函数及其辅助函数中。当b = 0b减少时,将其包围到unsigned int限制,然后继续添加堆栈,直到b恢复为1.

感谢@chris帮助调试,感谢@vsoftco建议无限递归。


我对C ++很陌生。我编写的程序有4个函数,其中3个是递归的(我怀疑递归函数与这个问题有关)。

基本上,我知道当我到达以下代码行时遇到了段错误:

    uint right = (n % pow(10, i)) / pow(10, i - 1);

此代码位于我的bool isPalindrome(uint)函数的for循环中。这是我与segfault有关的唯一信息。

我曾尝试在stackoverflow和google上寻找段错误示例,但我找不到任何与指针和类似内容相关的内容。

这里出了什么问题?任何和所有的帮助将不胜感激。另外,请解释你提出的任何建议,因为我对C ++还不熟悉,并打算尽可能多地学习。接下来是完整的源代码,我认为这对于这个问题是非常宝贵的。

/*
 * AUTHORS:        Thomas D. Fischer (a.k.a. gragas)
 * CREATION DATE:  ----:--:--        (YY:MM:DD)
 */

#include <iostream>
#include <time.h>

using namespace std;

typedef unsigned int uint;

bool isPalindrome(uint);
uint length(uint, uint count = 0);
uint pow(uint, uint);
uint powhelper(uint, uint, uint);

int main()
{
    clock_t start_time = clock();
    cout << "Running program..." << endl;

    cout << isPalindrome(12) << endl;

    cout << "Execution Time: " << double(clock() - start_time)/CLOCKS_PER_SEC;
}

bool isPalindrome(uint n)
{
    for(uint i = 1; i <= length(n)/2; i++)
    {
        uint left  = (n / pow(10, length(n) - i)) % 10;
        uint right = (n % pow(10, i)) / pow(10, i - 1);
        if( left != right )
            return false;
    }
    return true;
}

uint length(uint n, uint count)
{
    if(n != 0)
        return length(n /= 10, ++count);
    else
        return count;
}

uint pow(uint a, uint b)
{
    if(b != 1)
        return powhelper(a*a, --b, a);
    else
        return a;
}

uint powhelper(uint a, uint b, uint multiplier)
{
    if(b != 1)
        return powhelper(a*multiplier, --b, multiplier);
    else
        return a;
}

2 个答案:

答案 0 :(得分:3)

你的pow()函数不处理b = 0的情况。这发生在循环的第一次迭代中(我通过插入几个调试打印输出找到)。

在这种情况下--b溢出并变成一个非常大的数字,这会导致递归溢出堆栈。

段错误来自程序堆栈溢出。

答案 1 :(得分:2)

您的pow函数无法正确处理0的指数,您在循环的第一次迭代过程中会在该行上传入该指数。您考虑过使用std::pow吗?

进一步详细说明,在调用powhelper时,将指数从零递减。这被定义为模运算,所以你最终会得到一个非常大的数字,几乎可以肯定会导致堆栈溢出。