Segfault使用bool类型的向量

时间:2012-06-25 18:56:23

标签: c++ vector segmentation-fault boolean

我正在尝试解决编程难题并遇到一些困难。它与Project Euler problem 215类似,但宽度为3和4.5。无论如何,我最初通过强制逼近C中的组合来接近它,但我试图通过计算第一行中的所有组合并查看有多少有效方法将它们组合然后从那里开始来加速运行时。我认为这样做更容易使用布尔值向量(尝试过bitset但我不能使用它们,因为我没有在编译时可用的宽度),但我不是那种经验丰富的向量而且我已经做了一些让segfault神愤怒的事情。我只是看不到哪里。

当我提供程序参数时,我得到了分段错误11,所以这肯定是我做的,当我在GDB中运行回溯时,我得到以下内容:

#0  0x0000000100002645 in std::_Bit_reference::operator= ()
#1  0x0000000100001be2 in build ()
#2  0x0000000100002287 in main ()

我知道有些东西我没有看到。它只发生在实际调用build()时,但我包括main()以防万一我可能在调用时出错了。

#include <vector>

void build(std::vector<std::vector<bool> > possibilities, std::vector<bool> current, float width)
{
if(current.size() > 0)
{
    if(current.size() > width) return; // If we went over the specified width, bail out-invalid

    if (current.size() == width) // If we just matched the width for this row, push it on to our vector of possibilities
    {
        possibilities.push_back(current);
        return;
    }
}

// Try adding a block of length 3 and a block of length 4.5
std::vector<bool> branch1;
std::vector<bool> branch2;
if(current.size() > 0)
{
    branch1.assign( current.begin(), current.end() );
    branch2.assign( current.begin(), current.end() );

    branch1[ current.size() + 5 ] = 1;
    branch2[ current.size() + 8 ] = 1;
}
else
{
    branch1[5] = 1;
    branch2[8] = 1;
}
// Split off and check both branches
build(possibilities, branch1, width);
build(possibilities, branch2, width);
}

int main( int argc, char *argv[] )
{
if ( argc == 3 ) // Number of arguments should be 3-the program name, plus our width and height
{
    float width = (atof(argv[1]) * 2); // Width is assumed to be entered first, converting to integer
    int height = atoi(argv[2]); // The second argument should be height, ditto above
    if ( (width < 3) || (height < 1) ) // Catches non-number inputs (atof/i returns 0) and invalid entries
    {
        printf("Expected two numeric arguments, width and height, in that order.");
    }
    else // Continue the program
    {
        std::vector<bool> noo;
        std::vector<std::vector<bool> > possibilities;
        build(possibilities, noo, width);
        printf("%llu", (unsigned long long)possibilities.size());
    }
}
else
{
    printf("Expected two numeric arguments, width and height, in that order.");
}
}

1 个答案:

答案 0 :(得分:3)

您的noo向量:

std::vector<bool> noo;

build的第二个参数:

build(possibilities, noo, width);

是空的。但是,在build内,您可以根据该向量的大小执行一些操作:

std::vector<bool> branch1;
std::vector<bool> branch2;
if(current.size() > 0) //current is actually noo
{
    branch1.assign( current.begin(), current.end() );
    branch2.assign( current.begin(), current.end() );

    branch1[ current.size() + 5 ] = 1;
    branch2[ current.size() + 8 ] = 1;
}
else
{
    branch1[5] = 1;
    branch2[8] = 1;
}

由于它是空的,您将访问向量58的位置branch1branch2(它们也是空的),从而导致未定义的行为。

您应该以某种方式调整branch1branch2的大小,以便您不会执行越界访问。

这样:

std::vector<bool> branch1(someNumber);

会这样做,但你应该看看你的代码的逻辑,肯定还有其他错误。此外,您按价值传递参数,因此您制作了不必要的副本,并且您将看不到对来自possibilities的{​​{1}}向量进行的修改。