2014-01-26 34 views
1

我想用(0,0)的红色填充图像green.jpg,并用红色填充。我尝试在C++中执行此操作(因为Python递归很慢),并使用CImg作为映像库来获取和设置像素。这是我的程序。带有洪水填充的C++ SegFault

#include <iostream> 
#include <tuple> 
#include <vector> 
#include "CImg.h" 

using namespace cimg_library; 

int main() 
{ 
    CImg<unsigned char> im("green.jpg"); 
    int l = im.width(); 
    int w = im.height(); 
    int x = 0; 
    int y = 0; 

    auto newcol = std::make_tuple(255,0,0); 
    int R = im(x,y,0,0); 
    int G = im(x,y,0,1); 
    int B = im(x,y,0,2); 
    auto oldcol = std::make_tuple(R,G,B); 

    std::vector<std::tuple<int,int>> edge = {std::make_tuple(x,y)}; 

    while (edge.size() != 0) 
    { 
    std::vector<std::tuple<int,int>> newedge; 
     for (int e = 0; e < edge.size(); e++) 
     { 
      int a = std::get<0>(edge[e]); 
      int b = std::get<1>(edge[e]); 

      if (0 <= a <= l && 0 <= b <= w) 
      { 
       auto currcol = std::make_tuple(im(a,b,0,0),im(a,b,0,1),im(a,b,0,2)); 

       if (currcol == oldcol) 
       { 
         im(a,b,0,0) = std::get<0>(newcol); 
         im(a,b,0,1) = std::get<1>(newcol); 
         im(a,b,0,2) = std::get<2>(newcol); 
         newedge.push_back(std::make_tuple(a-1,b)); 
         newedge.push_back(std::make_tuple(a+1,b)); 
         newedge.push_back(std::make_tuple(a,b+1)); 
         newedge.push_back(std::make_tuple(a,b-1));   
       } 
      } 
     } 
     edge = newedge; 
    } 

    im.save("done.jpg");  
    return 0; 
} 

但是,我一直遇到SegFault,我找不到原因。我曾尝试使用gdb来调试程序,但它返回这个:

Program received signal SIGSEGV, Segmentation fault. 
0x000000000040b67c in std::_Head_base<2ul, unsigned char, false>::_Head_base<unsigned char&, void> (this=0x7fffffffdd10, 
[email protected]: <error reading variable>) at /usr/include/c++/4.8/tuple:140 

这显然是在元组头文件中。有人能告诉我SegFault是由什么引起的以及如何解决它?谢谢。

编辑:添加堆栈跟踪:

(gdb) bt 
#0 0x000000000040b67c in std::_Head_base<2ul, unsigned char, false>::_Head_base<unsigned char&, void> (this=0x7fffffffdd10, 
    [email protected]: <error reading variable>) at /usr/include/c++/4.8/tuple:140 
#1 0x000000000040b6c2 in std::_Tuple_impl<2ul, unsigned char>::_Tuple_impl<unsigned char&, , void>(unsigned char&) (this=0x7fffffffdd10, 
    [email protected]: <error reading variable>) at /usr/include/c++/4.8/tuple:262 
#2 0x000000000040b71e in std::_Tuple_impl<1ul, unsigned char, unsigned char>::_Tuple_impl<unsigned char&, unsigned char&, void> (
    this=0x7fffffffdd10, [email protected]: <error reading variable>) at /usr/include/c++/4.8/tuple:262 
#3 0x000000000040b7b1 in std::_Tuple_impl<0ul, unsigned char, unsigned char, unsigned char>::_Tuple_impl<unsigned char&, unsigned char&, unsigned char&, void> (this=0x7fffffffdd10, [email protected]: <error reading variable>) at /usr/include/c++/4.8/tuple:262 
#4 0x000000000040b832 in std::tuple<unsigned char, unsigned char, unsigned char>::tuple<unsigned char&, unsigned char&, unsigned char&, void> (
this=0x7fffffffdd10) at /usr/include/c++/4.8/tuple:405 
#5 0x000000000040b895 in std::make_tuple<unsigned char&, unsigned char&, unsigned char&>() at /usr/include/c++/4.8/tuple:862 
#6 0x0000000000402e5d in main() at fill.cpp:34 
+0

使用递归洪水填充很容易导致堆栈溢出。 –

+0

是的,但它不适用于15x15图像。另外,我没有使用递归堆栈内存。 – identicon

+0

在gdb中尝试'bt'并查看是否可以看到堆栈跟踪? – Mine

回答

1

我固定我自己的问题。在gdb中,我发现我的一个变量a等于-1,它超出了图像范围,导致内存问题和段错误。 if (0 <= a <= l && 0 <= b <= w)本应该抓住这一点,但显然a <= b <= c将无法​​在C++中正常工作。所以我把它改为if (0 <= a && a <= l && 0 <= b && b <= w),它工作。

谢谢大家的支持。

+0

请点击左边的复选标记将其标记为已接受的答案(我相信您可以在这之前等待两天)。 –

+0

是的,我正在等待这段时间结束。 – identicon