kompiliert hat er, also muss es was am algo sein...



  • angeregt von einem thema im forum wollt ich mal meinen alten "taschenrechner" auf der festplatte gesucht und gefunden und wollte ihn mal als klasse umsetzen. ich hab festgestellt, dass der alte schrott war und ich hab komplett neu angefangen.

    also jetzt hab ich die grundrechenoperationen implementiert und wollte testen. hat auch super funktioniert. bis ich der klasse "2*(3+2)" übergeben hab. da zeigte er mir auf einmal an:

    Debug Error!
    
    Program: ...icrosoft Visual Studio\MyProjects\2varfunk\Debug\2varfunk.exe
    
    DEMAGE: before Normal block(#46) at 0x00491F60
    
    (Press Retry to debug the application)
    
               [Abbrechen]   [Wiederholen]   [Ignorieren]
    

    ich hab zwar herrausgefunden an welcher stelle im programm er mir den fehler auswirft, aber nicht warum.

    was auch komisch ist, ist, dass (3+2)*2 funktioniert 2*(3+2) jedoch nicht. es scheint irgendwie was mit der KlammerAuf zu tun zu haben. mehr weiß ich auch nicht.

    hier ist mal der quellcode:

    //strfunction.h
    #ifndef strfunction_h_
    #define strfunction_h_
    
    #include <vector>
    #include <math.h>
    
    using namespace std;
    
    class strFunction
    {
    	public:
    		strFunction(const char* = 0);
    		~strFunction(void){delete function;}
    
    		double strfunc(double x = 0.0, double y = 0.0);
    
    	private:
    		vector<char> operators, numbuff;
    		vector<double> operands;
    		char* function;
    
    		int charcon(char);
    		void calc(void);
    		void bufftrans(void);
    		void bracetrace(void);
    		void opcalc(char*);
    		void numbufftest(void);
    };
    
    #endif
    
    //strfunction.cpp
    #ifndef strfunction_cpp_
    #define strfunction_cpp
    
    #include <vector>
    #include <math.h>
    #include "strfunction.h"
    
    using namespace std;
    
    //-----------------------------------------------------------------------------
    //-**Standartkonstruktor. Kann auch gleich einen Funktionsstring übernehmen***-
    //-----------------------------------------------------------------------------
    
    strFunction::strFunction(const char* func)
    {
    	if (*func)
    	{
    		const char* copyfunc = func;
    		int length = 0;
    		while(*copyfunc++) length++;
    		function = new char[length+1];
    		char* copyfunction = function;
    
    		while((*copyfunction++ = *func++));
    	}
    	else function = 0;
    }
    
    //-----------------------------------------------------------------------------
    //-**Übergibt einen entprechenden Zahlenwert für den empfangenen char zurück**-
    //-----------------------------------------------------------------------------
    
    int strFunction::charcon(char ch)
    {
        switch (ch)
        {
            case '.' : return 1; break;
            case '1' : return 1; break;
            case '2' : return 1; break;
            case '3' : return 1; break;
            case '4' : return 1; break;
            case '5' : return 1; break;
            case '6' : return 1; break;
            case '7' : return 1; break;
            case '8' : return 1; break;
            case '9' : return 1; break;
            case '0' : return 1; break;
            case 'x' : return 2; break;
            case 'y' : return 3; break;
            case ')' : return 4; break;
            case '(' : return 5; break;
            case '-' : return 6; break;
            case '+' : return 7; break;
            case '/' : return 8; break;
            case '*' : return 9; break;
            case '^' : return 10; break;
            default: return 0;
        }
    }
    
    //-----------------------------------------------------------------------------
    //-*********Verrechnet letzten Operator mit den letzten beiden Zahlen*********-
    //-----------------------------------------------------------------------------
    
    void strFunction::calc(void)
    {
        if (operators.size() != 0)
        {
            double y = operands.back();
            operands.pop_back();
            double x = operands.back();
            operands.pop_back();
            char operator_ = operators.back();
            operators.pop_back();
    
            switch (operator_)
            {
                case '^' : x = pow(x, y); break;
                case '*' : x = x * y; break;
                case '/' : x = x / y; break;
                case '+' : x = x + y; break;
                case '-' : x = x - y; break;
            }
            operands.push_back(x);
        }
    }
    
    //-----------------------------------------------------------------------------
    //-******Hängt den aktuellen Zahlenstring als double an den Zahlenvector******-
    //-----------------------------------------------------------------------------
    
    void strFunction::bufftrans(void)
    {
    	char numb[20];
    
    	for (int i = 0; i < numbuff.size(); i++)
    		numb[i] = numbuff.at(i);
    	numb[numbuff.size()] = 0;
    	numbuff.clear();
    	double x = atof(numb);//nur zu testzwecken aus push_back rausgezogen
    	operands.push_back(x);//<< HIER GIBT ER DEN FEHLER AUS
    }
    
    //-----------------------------------------------------------------------------
    //-**********Sucht nach der letzten offenen Klammer im Operatorvector*********-
    //-----------------------------------------------------------------------------
    
    void strFunction::bracetrace(void)
    {
    	while (operators.back() != '(')
    		calc();
    	operators.pop_back();
    }
    
    //-----------------------------------------------------------------------------
    //-*******Übergibt den Operator an calc(vector<double>&, vector<char>&)*******-
    //-----------------------------------------------------------------------------
    
    void strFunction::opcalc(char* func)
    {            
    	if (operators.size() > 0) 
    		if ((charcon(operators.back()) / 2) >= (charcon(*func) / 2))
    			calc();
    
    	operators.push_back(*func);
    }
    
    //-----------------------------------------------------------------------------
    //-****Überprüft, ob numbuff leer ist. Wenn nicht wird bufftrans ausgeführt***-
    //-----------------------------------------------------------------------------
    
    void strFunction::numbufftest(void)
    {
    	if (numbuff.size() != 0)
    		bufftrans();
    }
    
    //-----------------------------------------------------------------------------
    //-***************Gibt den char an die richtige Funktion weiter***************-
    //-----------------------------------------------------------------------------
    
    double strFunction::strfunc(double x, double y)
    {
    	char* func = this->function;
    
        while(*func != 0)
        {
    		switch (charcon(*func))
    		{
    			case 0 : break;
    			case 1 : numbuff.push_back(*func); break;
    			case 2 : operands.push_back(x); break;
    			case 3 : operands.push_back(y); break;
    			case 4 : numbufftest(); bracetrace(); break;//<< hier geht er dann rein
    			default : numbufftest(); opcalc(func);
    		}        
            func++;   
        }
    
        numbufftest();
    
    	while (operators.size() != 0)
            calc();
    
        return operands.at(0);
    }
    
    #endif
    
    //main.cpp
    #include <cstdlib>
    #include <iostream>
    #include "strfunction.h"
    
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        strFunction f1("(2*3)*2");//<< funktioniert
        strFunction f2("2*(3+2)");//<< funktoniert nicht
    //                       ^----bei diesem zeichen gibt er den fehler aus
        cout << f1.strfunc() << endl;
        cout << f2.strfunc() << endl;//hier gibts nen fehler
    
        //system("PAUSE");
        return 0;
    }
    

    ich benutze vc++ 6.0. mit dev-cpp ist es nicht besser. da gibt er garnichts aus.

    unter

    http://www.free-webspace.biz/MamboKurt

    ist des vc-project mit allem drin als zip zum download, falls einer das selber nachprüfen will

    also ich hab wirklich keine ahnung woran das liegen könnte. wenn mir einer sagen kann, woran das liegt, wäre ich demjenigen sehr verbunden. 👍

    .MamboKurt



  • void strFunction::calc(void)
    {
        if (operators.size() != 0)
        {
            double y = operands.back();
            operands.pop_back();
    
    /*********************************************************************
            long dummy = operands.size();
            // Hier greifst du daneben weil, wenn dummy = 0 gehts schief
            // => nachfolgend Speicherschreiber
            double x = operands.back();
    /*********************************************************************
    
            operands.pop_back();
            char operator_ = operators.back();
            operators.pop_back();
    
            switch (operator_)
            {
                case '^' : x = pow(x, y); break;
                case '*' : x = x * y; break;
                case '/' : x = x / y; break;
                case '+' : x = x + y; break;
                case '-' : x = x - y; break;
            }
            operands.push_back(x);
        }
    }
    

    Hab nur den Debugger angeworfen. Zum Algorithmus kann ich mich daher nicht
    äussern, aber es sind wohl nicht soviel Operanden wie erwartet anwesend.
    😃 🙂 😃



  • [Edit]: ja das is nicht mein prob.
    mein prob is, dass der auf einmal bei vector<float> operands kein push_back mehr machen will. normal sollte sowas doch immer gehen, oder?

    [Edit]: bin halt ne lahme sau am kboard

    .MamboKurt



  • Wie du siehst 😃 😃



  • weiß jemand, was der fehler heißt? das wäre ein guter anfang...

    .MamboKurt



  • Du hast einen Speicherschreiber, weisst du nicht was das ist oder was
    willst du wissen. 🙄



  • öhm...
    ich wüsste jetzt nicht, was du mit speicherschreiber meinst.
    was ist das?

    .MamboKurt



  • Du versuchst in nicht reserviertem Speicher zu schrieben!



  • aso
    ich dachte vector reserviert für mich wenn ich push_back aufrufe...

    .MamboKurt



  • MamboKurt schrieb:

    ich dachte vector reserviert für mich wenn ich push_back aufrufe...

    Das tut er auch. Aber der erste Aufruf von calc erfolgt bereits, wenn erst ein Element in operands ist. Und du holst zwei raus...



  • thx.
    funzt alles wie geschmiert.

    sieht nun so aus:

    double strFunction::strfunc(double x, double y)
    {
    	char* func = function;
    
        while(*func != 0)
        {
    		switch (charcon(*func))
    		{
    			case 0 : break;
    			case 1 : numbuff.push_back(*func); break;
    			case 2 : operands.push_back(x); break;
    			case 3 : operands.push_back(y); break;
    			case 4 : numbufftest(); bracetrace(); break;
    			case 5 : numbufftest(); operators.push_back(*func); break;//<<diese Zeile wurde eingefügt
    			default : numbufftest(); opcalc(func);
    		}        
            func++;   
        }
    
        numbufftest();
    
    	while (operators.size() != 0)
            calc();
    
        return operands.at(0);
    }
    

    .MamboKurt


Anmelden zum Antworten