tBane Temat założony przez niniejszego użytkownika |
[SFML 2.X] Narzędzie Fill - czyli wypełnianie danego obszaru kolorem » 2025-09-11 19:41:00 Cześć Wszystkim! Próbuję napisać poprawnie narzędzie Fill w moim programie do edycji grafiki. Narzędzie to ma działać w ten sposób, że klikamy w dane miejsce na canvasie i wypełnia cały możliwy obszar zadanym kolorem. Napisałem pod to funkcje jedną główną i drugą rekurencyjną. Narzędzie czasem działa a czasem wyrzuca błąd mallock. Log z błędem _NODISCARD _Ret_notnull_ _Post_writable_byte_size_(size) _VCRT_ALLOCATOR _CRT_SECURITYCRITICAL_ATTRIBUTE void* __CRTDECL operator new(size_t const size) { for (;;) { if (void* const block = malloc(size)) { return block; }
if (_callnewh(size) == 0) { if (size == SIZE_MAX) { __scrt_throw_std_bad_array_new_length(); } else { __scrt_throw_std_bad_alloc(); } }
// The new handler was successful; try to allocate again... }
Kod narzędziavoid fill( sf::Color colorToEdit, sf::Color newColor, sf::Vector2i tile ) { sf::IntRect tileRect = sf::IntRect( 0, 0, animation->getCurrentLayer()->image.getSize().x, animation->getCurrentLayer()->image.getSize().y ); if( !tileRect.contains( tile ) ) return; if( colorToEdit == newColor ) return; if( animation->getCurrentLayer()->image.getPixel( tile.x, tile.y ) == colorToEdit ) { animation->getCurrentLayer()->image.setPixel( tile.x, tile.y, newColor ); fill( colorToEdit, newColor, sf::Vector2i( tile.x - 1, tile.y ) ); fill( colorToEdit, newColor, sf::Vector2i( tile.x + 1, tile.y ) ); fill( colorToEdit, newColor, sf::Vector2i( tile.x, tile.y - 1 ) ); fill( colorToEdit, newColor, sf::Vector2i( tile.x, tile.y + 1 ) ); } }
void fillPixels( sf::Color color ) { sf::Vector2i tile = worldToTile( worldMousePosition, position, zoom, zoom_delta ); sf::Color colorToEdit = animation->getCurrentLayer()->image.getPixel( tile.x, tile.y ); fill( colorToEdit, color, tile ); }
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-09-11 19:50:39 Chyba znalazłem rozwiązanie. Zamiast stosować rekurencję użyłem std::vector do przechowywania współrzędnych pikseli i tym sposobem omijam przepełnienie .. stosu ? w każdym bądź razie pamięć wystarcza :-) void fill( sf::Color colorToEdit, sf::Color newColor, sf::Vector2i pixelCoords ) { if( colorToEdit == newColor ) return; sf::IntRect imageRect = sf::IntRect( 0, 0, animation->getCurrentLayer()->image.getSize().x, animation->getCurrentLayer()->image.getSize().y ); std::vector < sf::Vector2i > pixels; pixels.push_back( pixelCoords ); while( !pixels.empty() ) { sf::Vector2i t = pixels.back(); pixels.pop_back(); if( !imageRect.contains( t ) ) continue; if( animation->getCurrentLayer()->image.getPixel( t.x, t.y ) == colorToEdit ) { animation->getCurrentLayer()->image.setPixel( t.x, t.y, newColor ); pixels.push_back( sf::Vector2i( t.x - 1, t.y ) ); pixels.push_back( sf::Vector2i( t.x + 1, t.y ) );; pixels.push_back( sf::Vector2i( t.x, t.y - 1 ) );; pixels.push_back( sf::Vector2i( t.x, t.y + 1 ) );; } } }
void fillPixels( sf::Color color ) { sf::Vector2i tile = worldToTile( worldMousePosition, position, zoom, zoom_delta ); sf::Color colorToEdit = animation->getCurrentLayer()->image.getPixel( tile.x, tile.y ); fill( colorToEdit, color, tile ); }
|
|
pekfos |
» 2025-09-11 22:18:53 Co to za log z błędem? W tym kodzie nie widać dynamicznej alokacji pamięci, a przepełnienie stosu nie daje takiego objawu. |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-09-11 22:34:22 IDE nie pokazywało logu z błędem kompilacji tylko przekierowało do tego kodu, który wstawiłem. ChatGPT zasugerował, że to przez przepełnienie pamięci więc napisałem kod z std::Vector. Dobry jest ten kod? |
|
pekfos |
» 2025-09-11 22:43:50 W sensie że uruchomiłeś program pod debuggerem i wywaliło błąd w tym fragmencie? Masz na repo tą wersję do uruchomienia? |
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-09-11 22:46:51 |
|
pekfos |
» 2025-09-11 23:03:15 Dobra, to jest przepełnienie stosu tylko jako "log" wziąłeś kod źródłowy, zamiast faktyczny komunikat błędu który wyskakuje. Unhandled exception at 0x00007FFA9FC1B3C2 (ntdll.dll) in xxxxx.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x0000003BB34F3FD8).
|
|
tBane Temat założony przez niniejszego użytkownika |
» 2025-09-11 23:05:23 Mi takiego błędu nie pokazuje, tylko wyświetla nową zakładkę z kodem, więc zgadywałem trochę. Czy mój drugi kod rozwiązuje ten problem? To znaczy czy to rozwiazanie jest optymalne ? |
|
« 1 » 2 |