为什么使用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
最满意答案
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.
相关问答
更多-
在java中初始化具有动态大小的二维字符串数组(initialize two dimensional string array with dynamic size in java)[2024-02-08]
您可以使用以下类将数据存储在HashMap ,并将其转换为二维字符串数组。 public class ArrayStructure { private HashMapmap = 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.
-
调整动态字符串数组的大小(Resizing dynamic string array)[2021-07-03]
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; 。 这是合法的。 但是你不 ...
-
C调整动态数组的大小(C resizing a dynamic array)[2022-02-06]
您的函数_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 ...