vector-Klasse, die auf dem Stack liegt



  • Hiho,

    ich habe für einen SVO einen rekursiven Algorithmus, den ich umgeschrieben habe, sodass er iterativ abläuft. Dazu benutze ich 2 Stacks. Die Rekursionstiefe ist 10-15. Bisher verwende ich std::vector als Stack (mit einem reserve beim Start, um Neuallokationen zu verhindern). Ich wollte nun testen, ob es was bringt, wenn die Daten auf dem Stack liegen und nicht auf dem Heap (evtl. durch besseres Caching weil die Daten enger zusammen liegen).
    Prinzip: ein Array auf den Stack knallen und mit placement new/placement delete meine Objekte darin erzeugen.

    Das ist meine Klasse, welche die Daten halten soll:
    //

    template<typename T, int count>
    class stack_vector
    {
    	public:
    		//
    		using value_type = T;
    
    		//
    		template<typename... Args>
    		void emplace_back(Args... args)
    		{
    			auto address = reinterpret_cast<T*>(m_rawData) + m_size;
    			new(address) T(args...);
    
    			++m_size;
    		}
    
    		//
    		void pop_back()
    		{
    			--m_size;
    
    			auto address = reinterpret_cast<T*>(m_rawData) + m_size;
    
    			address->~T();
    		}
    
    		//
    		bool empty() const { return m_size == 0; }
    
    		//
    		value_type& back()
    		{
    			auto address = reinterpret_cast<T*>(m_rawData) + m_size - 1;
    
    			return *address;
    		}
    
    	private:
    		//
    		unsigned int m_size { 0 };
    		//
    		unsigned char m_rawData[sizeof(T) * count];
    };
    

    Und das ist de Datentype, der in den Stack reinsoll.

    //
    struct SvoLvlData
    {
    	//
    	SvoLvlData(Voxel& voxel, RealT halfLength, unsigned char currHierarchyDepth, unsigned char remainIndex) : voxel(voxel), halfLength(halfLength),
    																													  currHierarchyDepth(currHierarchyDepth),
    																														  remainIndex(remainIndex), testedChildren(0)
    	{ }
    
    	//
    	Voxel& voxel;
    
    	//
    	RealT halfLength;
    
    	//
    	unsigned char currHierarchyDepth;
    
    	//
    	unsigned char remainIndex;
    
    	//
    	unsigned char testedChildren;
    };
    

    Mein Problem ist nun: wenn ich back() aufrufe, stimmt die Voxel-Referenz nicht mehr. Die Adressberechnung sieht gut aus, die einfachen Daten hauen auch hin, wenn ich im Debugger reinschaue. Aber die Voxel-Referenz stimmt nicht mehr. Ist in meinem Code ein Fehler oder macht mir eine Compiler-Optimierung da irgendetwas "kaputt"? Ich bin da grad ratlos, warum es nicht geht.

    VG

    Pellaeon



  • Perfect forwarding geht mit std::forward.

    template<typename... Args>
            void emplace_back(Args&&... args)
            {
                auto address = reinterpret_cast<T*>(m_rawData) + m_size;
                new(address) T(std::forward<Args>(args)...);
    
                ++m_size;
            }
    

    und für Referenzen mit std::ref in einen reference_wrapper verpacken.



  • *an den Kopf greif* stiiiimmt. Danke!


Anmelden zum Antworten