首页 \ 问答 \ 为什么使用Flood Fill算法时会出现java.lang.StackOverflowError?(Why do I get java.lang.StackOverflowError when using Flood Fill algorithm?)

为什么使用Flood Fill算法时会出现java.lang.StackOverflowError?(Why do I get java.lang.StackOverflowError when using Flood Fill algorithm?)

我的程序应该用borderFill4方法中指定的颜色(开始处用黑色和白色)填充不规则的形状。 这里是myImage.png的链接: https ://dl.dropbox.com/u/41007907/myImage.png我使用一个非常简单的洪水填充算法,但它不能以某种方式工作...这里是完整的代码:

  import java.awt.Color;
  import java.awt.Container;
  import java.awt.Image;
  import java.awt.image.BufferedImage;
  import javax.swing.ImageIcon;
  import javax.swing.JFrame;
  import javax.swing.JLabel;

      public class MyPolygon extends JFrame {

private JLabel my;

public MyPolygon() throws InterruptedException {
    createMy();
}

private void createMy() throws InterruptedException {
    Container contentPane = getContentPane();
    contentPane.setBackground(Color.WHITE);
    contentPane.setLayout(null);
    contentPane.setSize(1000, 700);

    my = new JLabel();
    my.setIcon(new ImageIcon("myImage.png"));
    my.setBounds(50, 50, 300, 300);
    contentPane.add(my);

    setSize(1000, 700);
    setVisible(true);
    setLocationRelativeTo(null);

    int fill = 100;
    boundaryFill4(100, 100, fill, 50);
}

// Flood Fill method
public void boundaryFill4(int x, int y, int fill, int boundary) {
    int current;
    current = getPixel(x, y);
    if ((current >= boundary) && (current != fill)) {
        setPixel(x, y, fill);
        boundaryFill4(x + 1, y, fill, boundary);
        boundaryFill4(x - 1, y, fill, boundary);
        boundaryFill4(x, y + 1, fill, boundary);
        boundaryFill4(x, y - 1, fill, boundary);
    }
}

// Getting the color integer at specified point(x, y)
private int getPixel(int x, int y) {
    Image img = ((ImageIcon) my.getIcon()).getImage();
    BufferedImage buffered = new BufferedImage(img.getWidth(null),
            img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
    buffered.getGraphics().drawImage(img, 0, 0, null);
    Color c = new Color(buffered.getRGB(x, y));
    int current = buffered.getRGB(x, y);
    return current;
}

// Setting the color integer to a specified point(x, y)
private void setPixel(int x, int y, int fill) {
    Image img = ((ImageIcon) my.getIcon()).getImage();
    BufferedImage buffered = new BufferedImage(img.getWidth(null),
            img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
    buffered.getGraphics().drawImage(img, 0, 0, null);
    int red = fill;
    int green = fill;
    int blue = fill;
    Color c = new Color(buffered.getRGB(x, y));
    c = new Color(red, green, blue);
    buffered.setRGB(x, y, c.getRGB());
}

// Main method
public static void main(String args[]) throws InterruptedException {
    MyPolygon my = new MyPolygon();
    my.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

为什么我会收到StackOverflow错误? 我如何纠正它,以便我的代码工作?


My program is supposed to fill in a non-regular shape with a color (black and white for the beginning) that I specify in the boundaryFill4 method. Here is the link to myImage.png: https://dl.dropbox.com/u/41007907/myImage.png I use a very simple flood fill algorithm, but it does not work somehow... Here is the FULL code:

  import java.awt.Color;
  import java.awt.Container;
  import java.awt.Image;
  import java.awt.image.BufferedImage;
  import javax.swing.ImageIcon;
  import javax.swing.JFrame;
  import javax.swing.JLabel;

      public class MyPolygon extends JFrame {

private JLabel my;

public MyPolygon() throws InterruptedException {
    createMy();
}

private void createMy() throws InterruptedException {
    Container contentPane = getContentPane();
    contentPane.setBackground(Color.WHITE);
    contentPane.setLayout(null);
    contentPane.setSize(1000, 700);

    my = new JLabel();
    my.setIcon(new ImageIcon("myImage.png"));
    my.setBounds(50, 50, 300, 300);
    contentPane.add(my);

    setSize(1000, 700);
    setVisible(true);
    setLocationRelativeTo(null);

    int fill = 100;
    boundaryFill4(100, 100, fill, 50);
}

// Flood Fill method
public void boundaryFill4(int x, int y, int fill, int boundary) {
    int current;
    current = getPixel(x, y);
    if ((current >= boundary) && (current != fill)) {
        setPixel(x, y, fill);
        boundaryFill4(x + 1, y, fill, boundary);
        boundaryFill4(x - 1, y, fill, boundary);
        boundaryFill4(x, y + 1, fill, boundary);
        boundaryFill4(x, y - 1, fill, boundary);
    }
}

// Getting the color integer at specified point(x, y)
private int getPixel(int x, int y) {
    Image img = ((ImageIcon) my.getIcon()).getImage();
    BufferedImage buffered = new BufferedImage(img.getWidth(null),
            img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
    buffered.getGraphics().drawImage(img, 0, 0, null);
    Color c = new Color(buffered.getRGB(x, y));
    int current = buffered.getRGB(x, y);
    return current;
}

// Setting the color integer to a specified point(x, y)
private void setPixel(int x, int y, int fill) {
    Image img = ((ImageIcon) my.getIcon()).getImage();
    BufferedImage buffered = new BufferedImage(img.getWidth(null),
            img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
    buffered.getGraphics().drawImage(img, 0, 0, null);
    int red = fill;
    int green = fill;
    int blue = fill;
    Color c = new Color(buffered.getRGB(x, y));
    c = new Color(red, green, blue);
    buffered.setRGB(x, y, c.getRGB());
}

// Main method
public static void main(String args[]) throws InterruptedException {
    MyPolygon my = new MyPolygon();
    my.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

Why do I get StackOverflow error? How can I correct for it so that my code works?


原文:https://stackoverflow.com/questions/15896898
更新时间:2023-04-24 20:04

最满意答案

memcpy( newArr, hash_array, hash_array_length * sizeof(string) );

这行是非常危险的,std :: string不是普通的旧数据类型,你不能确保memcpy可以正确地初始化它,它可能导致未定义的行为,这是c ++(或编程)最讨厌的行为之一。

此外,有一个更好,更安全(在大多数情况下)的解决方案,在c ++中创建一个动态字符串数组,只需使用矢量

//create a dynamic string array with newSize and initialize them with "0"
//in your case, I don't think you need to initialize it with "0"
std::vector<std::string> newArr(newSize, "0"); 

如果hash_array与newArr(std :: vector)的类型相同,那么复制它的方式非常简单。

C ++ 98

std::copy(hash_array.begin(), hash_array.end(), newArr.begin());

C ++ 11

std::copy(std::begin(hash_array), std::end(hash_array), std::begin(newArr));

更好地将c ++视为一种新语言,它有太多不同于c的东西。 此外,有很多像样的免费IDE,比如code :: blocks和QtCreator devc ++是一个差不多死的项目。

如果您不熟悉c ++,那么c ++ primer 5是一本很好的书。


memcpy( newArr, hash_array, hash_array_length * sizeof(string) );

This line is extremely dangerous, std::string is not a plain old data type, you can't make sure that memcpy could initialize it correctly, it may cause undefined behavior, one of the most nasty behavior of c++(or programming).

Besides, there are a better and safer(in most of the times) solution to create a dynamic string array in c++, just use vector

//create a dynamic string array with newSize and initialize them with "0"
//in your case, I don't think you need to initialize it with "0"
std::vector<std::string> newArr(newSize, "0"); 

if the hash_array has the same type as newArr(std::vector) The way of copy it is very easy.

c++98

std::copy(hash_array.begin(), hash_array.end(), newArr.begin());

c++11

std::copy(std::begin(hash_array), std::end(hash_array), std::begin(newArr));

Better treat c++ as a new language, it has too many things are different from c. Besides, there are a lot of decent free IDE, like code::blocks and QtCreator devc++ is a almost dead project.

If you are new to c++, c++ primer 5 is a good book to start.

相关问答

更多
  • 您可以使用以下类将数据存储在HashMap ,并将其转换为二维字符串数组。 public class ArrayStructure { private HashMap map = new HashMap(); private int maxRow = 0; private int maxColumn = 0; public ArrayStructure() { } public void add( ...
  • 您不能以这种方式初始化零大小的数组,因为您必须动态分配内存。 只有在类型定义中指定尺寸时,才能执行所需操作。 在这里查看我对类似问题的回答。 You cannot initialize zero-sized arrays this way, because you have to dynamically allocate the memory. You can only do what you do if you specify the dimensions in the type definition. ...
  • 不要在C ++中使用malloc 。 它不运行字符串的构造函数,因此不为存储在其中的动态char数组分配空间。 请尝试使用new[]运算符或智能指针。 string **arr; arr = new string*[height]; for (int i = 0; i < height; i++) arr[i] = new string[width]; c ++ string只是动态char数组的一种包装,必须进行初始化(它应该为其分配内存)。 通过使用malloc您不会调用构造函数,从而导致访问 ...
  • 您可以像这样使用Arrays.copyOfRange String[] a = {"a","b","c","d","r","g","f","h", ...}; String[] b = Arrays.copyOfRange(a, 0, 1000, String[].class); String[] c = Arrays.copyOfRange(a, 1000, a.length, String[].class); 但是如果'a'的长度小于1000就会崩溃,所以你可以这样做 ...
  • 我编写了一些java代码来将我的HashMap转换为List而不是String [],并且ibatis使用List.size方法工作得更好。 I wrote some java code to convert my HashMap to have a List instead of String[] and ibatis worked much better with the List.size method.
  • memcpy( newArr, hash_array, hash_array_length * sizeof(string) ); 这行是非常危险的,std :: string不是普通的旧数据类型,你不能确保memcpy可以正确地初始化它,它可能导致未定义的行为,这是c ++(或编程)最讨厌的行为之一。 此外,有一个更好,更安全(在大多数情况下)的解决方案,在c ++中创建一个动态字符串数组,只需使用矢量 //create a dynamic string array with newSize and i ...
  • 您可以创建一个非常简单的类,它可以让您模拟动态数组,而不会暴露它的添加/删除方法等(您可以控制您公开的方法)。 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication2 { class Program { static void Main(st ...
  • 当你有一个type valueName[]数组参数的函数时,你只需将该数组参数的地址传递给函数。 调用函数具有该数组的所有权。 除了函数签名之外,您还必须考虑调用者和被调用函数之间的契约,该契约定义了指针传递的数据的所有权。 您的函数AddInfo获取一个由指针传递的数组,并且调用函数期望在函数调用之后数据可用。 因此,当您delete []in时,该功能违反了合同。 当您使用in=temp;分配新值时in=temp;您的函数in as(local)变量中使用参数in=temp; 。 这是合法的。 但是你不 ...
  • 您的函数_dynArrSetCapacity不能按预期工作,问题在于以下几行: v->capacity = newCap; v->size = newArr->size; v = newArr; //point v to new array } 最后一条指令基本没用。 v是一个指针。 更改不会影响_dynArrSetCapacity之外的实际使用指针。 因此在addDynArr v->data为0 ,你会得到一个分段错误: _dynArrSe ...
  • 如果你发现自己试图将sizeof()用于任何 动态大小的东西 ,那么你做错了。 记住这一点。 sizeof()在此代码中重复使用不正确。 动态尺寸计数必须由您管理; 可以使用这些计数结合所存储项目的基本类型的sizeof()来管理以字节为单位的分配大小要求。 鉴于: #include #include int main(int argc, char *argv[]) { int i = 0; int arrayIndexes = 2; c ...

相关文章

更多

最新问答

更多
  • python的访问器方法有哪些
  • 使用Zend Framework 2中的JOIN sql检索数据(Retrieve data using JOIN sql in Zend Framework 2)
  • 透明度错误IE11(Transparency bug IE11)
  • linux的基本操作命令。。。
  • 响应navi重叠h1和nav上的h1链接不起作用(Responsive navi overlaps h1 and navi links on h1 isn't working)
  • 在C中读取文件:“r”和“a +”标志的不同行为(Reading a File in C: different behavior for “r” and “a+” flags)
  • NFC提供什么样的带宽?(What Kind of Bandwidth does NFC Provide?)
  • 元素上的盒子阴影行为(box-shadow behaviour on elements)
  • Laravel检查是否存在记录(Laravel Checking If a Record Exists)
  • 设置base64图像的大小javascript - angularjs(set size of a base64 image javascript - angularjs)
  • 想学Linux 运维 深圳有哪个培训机构好一点
  • 为什么有时不需要在lambda中捕获一个常量变量?(Why is a const variable sometimes not required to be captured in a lambda?)
  • 在Framework 3.5中使用服务器标签<%=%>设置Visible属性(Set Visible property with server tag <%= %> in Framework 3.5)
  • AdoNetAppender中的log4net连接类型无效(log4net connection type invalid in AdoNetAppender)
  • 错误:发送后无法设置标题。(Error: Can't set headers after they are sent. authentication system)
  • 等待EC2实例重启(Wait for an EC2 instance to reboot)
  • 如何在红宝石中使用正则表达式?(How to do this in regex in ruby?)
  • 使用鼠标在OpenGL GLUT中绘制多边形(Draw a polygon in OpenGL GLUT with mouse)
  • 江民杀毒软件的KSysnon.sys模块是什么东西?
  • 处理器在传递到add_xpath()或add_value()时调用了什么顺序?(What order are processors called when passed into add_xpath() or add_value()?)
  • sp_updatestats是否导致SQL Server 2005中无法访问表?(Does sp_updatestats cause tables to be inaccessible in SQL Server 2005?)
  • 如何创建一个可以与持续运行的服务交互的CLI,类似于MySQL的shell?(How to create a CLI that can interact with a continuously running service, similar to MySQL's shell?)
  • AESGCM解密失败的MAC(AESGCM decryption failing with MAC)
  • SQL查询,其中字段不包含$ x(SQL Query Where Field DOES NOT Contain $x)
  • PerSession与PerCall(PerSession vs. PerCall)
  • C#:有两个构造函数的对象:如何限制哪些属性设置在一起?(C#: Object having two constructors: how to limit which properties are set together?)
  • 平衡一个精灵(Balancing a sprite)
  • n2cms Asp.net在“文件”菜单上给出错误(文件管理器)(n2cms Asp.net give error on Files menu (File Manager))
  • Zurb Foundation 4 - 嵌套网格对齐问题(Zurb Foundation 4 - Nested grid alignment issues)
  • 湖北京山哪里有修平板计算机的