Dziwna sytuacja z parametrami konstruktora

0

Witajcie :)
Stworzyłem sobie klase Window reprezentującą okno w SFMLu (dokładniej teksturke okna, czyli co sie tam chce).
Klasa dziedziczy z klas sf::Transformable oraz sf::Drawable, miała być tylko interfejsem, ale jednak jest zwykłą klasą przeznaczoną do dziedziczenia (działa poprawnie).
Następnie, w osobnym projekcie testowałem sobie to okienko i działało poprawnie (konstruktor też).
Stworzyłem instancje klasy w projekcie głównym w którym troche kodu już jest i bardzo sie zdziwiłem, mianowicie aplikacja wywala sie gdy przekazuje coś przez konstruktor.
W tym testowym projekcie teksturke do okna podawałem w konstruktorze w taki sposób Window(sf::Texture* _tex, sf::Vector2f posit) i bylo ok, działało.
W tym "właściwym" jak już nadmieniłem, przekazanie czegokolwiek przez konstruktor kończy się fiaskiem, z problemem poradziłem sobie tworząc setter setTexture(sf::Texture* _tex) ale zaciekawił mnie na tyle że sie o to pytam( no i w przypadku gdyby zdarzyło mi sie kiedyś coś podobnego - będe wiedział )
Kodu nie daje bo jest go mało i raczej nie jest istotny, podejrzewam że chodzi o jakąś (bardzo zawiłą :D)zawiłość c++a.

0

Bez kodu jestem w stanie powiedzieć Ci tylko tyle, że gdzieś strzeliłeś byka.

0

HPP

 
#pragma once
#include <SFML/Graphics.hpp>
class Window : public sf::Drawable, public sf::Transformable
{
    public:
        Window();
        void         setTexture(sf::Texture*);
        virtual void draw(sf::RenderTarget &, sf::RenderStates) const;
    protected:
        sf::Texture *_bg1 = nullptr;
        sf::Sprite _background;
        sf::Vector2f position;
        sf::Vector2f size;
};


CPP

 
Window::Window(sf::Texture *tex,sf::Vector2f _position)
: _bg1(tex)
, _background(*tex)
, position(_position)
, size(tex->getSize().x, tex->getSize().y)
{
	setPosition(_position);
}
void Window::draw(sf::RenderTarget& target, sf::RenderStates states) const{
	states.transform *= getTransform();
	states.texture = _bg1;
	target.draw(_background,states);
}

@spartanPAGE Cóż, też byłem tego święcie przekonany że literówka czy coś takiego ale nope, było ok.
Problem objawiał sie przy wykonywaniu w innym kontekscie co mi sie jescze nie zdarzyło.

2

jesli gdziekolwiek zrobiles cos takiego, to sie predzej czy pozniej sypnie:

class A {
Window* wnd;
public:
A() {
  sf::Texture tex = ....;
  sf::Vector2f pos = ...;
  wnd = new Window(&tex, pos);
}

void foo() {
  // jakakolwiek operacja na oknie ktora dotyka tekstury = sypnie sie
}
0

Dobra, a jak to wywołujesz?
Btw,

  1. Powinieneś trzymać tekstury w jakimś zarządcy, nie surowo
  2. Zwykłe skopiowanie twojego obiektu spowoduje wyciek i podwójne zwalnianie jednego zasobu.
0

Wywołuje tak

    Window win;
    win.setTexture(&t);
 

Wczesniej było

 
    Window win(&texturka, pozycja);

Resource manager jest w budowie i dlatego textury są hard-coded.
A co do kopiowania to z założenia obiekt nie jest przeznaczony do kopiowania (Uznałem to za nie potrzebne, bo nie widze potrzeby kopiowania okna ale fakt - rule of three mi sie kłania ).

0

Jeśli nie chcesz, żeby można było takowy obiekt kopiować - musisz co nie co oznaczyć jako delete.
Co do menadżera to podsyłałem Ci już gotowe rozwiązanie, które możesz ewentualnie okroić do swoich potrzeb.

0

Pokaz skad sie wzielo t tutaj:

Proxima napisał(a):

Wywołuje tak

    Window win;
    win.setTexture(&t);
 

Wczesniej było

 
    Window win(&texturka, pozycja);

Resource manager jest w budowie i dlatego textury są hard-coded.
A co do kopiowania to z założenia obiekt nie jest przeznaczony do kopiowania (Uznałem to za nie potrzebne, bo nie widze potrzeby kopiowania okna ale fakt - rule of three mi sie kłania ).

To jest bardzo podobne do tego przykladu co pozkazalem. Jesli t jest na stosie to obiekt zostanie zniszczony w tym samym momencie co skonczy sie scope w ktorym zostal wrzucony na stos, a to najczesciej dzieje sie dosc szybko. Zaraz po zniszczeniu obiektu Twoj wskaznik wskazuje na przypadkowe miejsce na stosie i jesli to Ci sie nie sypnie od razu to bedziesz w dosc nieciekawej sytuacji gdzie moze Ci sie cos sypnac w zupelnie losowym miejscu

0

@krwq
Właśnie to sie nie dzieje bo teksturka jest deklarowana w main (normalnie, nie wskaźnik) i istnieje do końca programu, a ja przekazuje tylko jej adres.
Najdziwniejsze jest to, że nieistotne co przekaże (np typ wbudowany w sfma sf::Vector2f) i też sie wywala właśnie to mnie mocno zdziwiło (na tyle że aż odpaliłem debugiera ale sie zbytnio nie lubimy i wiele nie wykumałem).

0

pokaz najmniejszy mozliwy kod ktory sie sypie i error

0

Hihoo!
Nie dało mi to spokoju i wczoraj w nocy zastanawiałem się co tam było źle, częściowo problem odnalazłem, niestety, nie udało mi sie odtworzyć błędu związanego z wywalaniem po przekazaniu byle czego przez argumenty, ale znalazłem błąd z teksturą który był banalny i wynikał z mojej nieuwagi.
Opowiem dokładnie jak to było.
Przypadek testowy czyli ten który chodził nie był kompilowany w IDE tylko w zwykłym edytorze komendą z palca g++ ...... i tam pliki tj. teksturki były położone w tym samym folderze co exe, działało.
Natomiast po przeniesieniu do "innego kontekstu" czyli w tym przypadku IDE, mechanizm ten nie wiem czemu działa nieco inaczej, mimo że w execu wpisane są nazwy plików "na luźno" czyli że pliki powinny być w tym samym folderze co exec, natomiast tak sie nie dzieje, code::blocks nie wiadomo czemu (i jak to w ogóle możliwe) szuka tych plików w głównym katalogu projektu (może jakieś dowiązanie tworzy, idk) czyli nie bin/Debug/.
Co dziwne, sfml w tamtym przypadku nie wypisywał na stdout "Unable to open file", natomiast program kończył sie SIGFPE, sprawdziłem debugerem gdzie dokładnie i jedną z przyczyn była (podczas korzystania z podklasy klasy Window)
sf::Int32 tv = GID / (_tex->getSize().x / tile_height);
Gdzie _tex->getSize().x wynosiło zero, w wyniku czego wykonywane było dzielenie przez zero.
To tak pokrótce, wiem że to jescze nie jest rozwiązanie, ale cośniecoś jestem już dalej :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1