Zugriffsverletzung beim Schreiben an Position 0x0......



  • hallo zusammen

    ich habe mit meinem folgenden Programm ein Problem, in der Zeile 21 (wohl dann auch 26 und 32 bekomme ich folgende Warnung die zum abbruch/stopp des programmes führt

    Unbehandelte Ausnahme bei 0x00411c2e in BigInt-Schulv.exe: 0xC0000005: Zugriffsverletzung beim Schreiben an Position 0x00646000.
    

    nur leider komm ich mit meinen derzeitigen wissen leider nicht weiter (in der Schule jedes Jahr ne andere PR-Sprache....)

    eine Warnung in Zeile 86 taucht ebenso noch auf

    Warnung	1	warning C4172: Adresse einer lokalen Variablen oder eines temporären Werts wird zurückgegeben
    

    ich hoffe mir kann wer so schnell wie möglich weiterhelfen, hab scho alles probiert, half nix

    mfg und vielen dank schonmal

    Fanati_C

    #include <iostream>
    using namespace std;
    class
    	BigInt
    {
    	char *zahl;
    	char vorzeichen;
    	int len;
    	BigInt addiere(BigInt op1, BigInt op2)
    	{
    		BigInt erg(0);
    		int u=0,i;
    		erg.zahl=new char[erg.len=((op1.len>op2.len)?op1.len:op2.len)+1];
    		erg.vorzeichen='+';
    		for(i=0; (op1.len>op2.len)?op1.len:op2.len; i++)
    		{
    			if(op1.len<i || op2.len<i)
    			{
    				if(op1.len<i)
    				{
    					erg.zahl[i]=(u+=op2.zahl[i])%10;
    					u/=10;
    				}
    				else
    				{
    					erg.zahl[i]=(u+=op1.zahl[i])%10;
    					u/=10;
    				}
    			}
    			else
    			{
    				erg.zahl[i]=(u+=op1.zahl[i]+op2.zahl[i])%10;
    				u/=10;
    			}
    		}
    		erg.zahl[i]=u;
    		return erg;
    	}
    
    public:
    	BigInt(int x)
    	{
    		if (x<0)
    		{
    			vorzeichen='-';
    			x=-x;
    		}
    		else
    		{
    			vorzeichen='+';
    		}
    		int y,i;
    		y=x;
    		for (i=0;y>0;i++)
    		{
    			y/=10;
    		}
    		zahl=new char[len=(i < 1)?1:i];
    		for (y=x,i=0;y>0;i++)
    		{ 
    			zahl[i]=y%10;
    			y/=10;
    		}
    	}
    		BigInt(char d[])
    		{
    			//int i=0;
    			//if(d[i]);
    			//for(i; d[i],m
    		}
    	void print (void)
    	{
    		int i;
    		cout<<vorzeichen;
    		for (i=len;i>-1;i--)
    		{
    			if(zahl[i]>=(char)0&&zahl[i]<=(char)9)
    				cout << (char) (zahl[i]+'0');
    		}
    		cout<<endl;
    	}
    	friend bool operator<(const BigInt &a, BigInt &b);
    
    	BigInt &operator+(const BigInt &a)
    	{
    		return addiere(*this, a);
    	}
    
    };
    
    bool operator<(const BigInt &a, BigInt &b) //<- bool friend operator <(...)
    		{
    			int i;
    			if(a.vorzeichen=='-' && b.vorzeichen=='+')return true; //-<+
    			if(a.vorzeichen=='+' && b.vorzeichen=='-')return true; //+<-
    			if (a.len<b.len)return ('+'==a.vorzeichen)?true:false;
    			if (a.len<b.len)return ('+'==a.vorzeichen)?false:true;
    			for(i=a.len-1; i>=0; i--)
    			{
    				if(a.zahl[i]<b.zahl[i])return ('+'==a.vorzeichen)?true:false;
    				if(a.zahl[i]>b.zahl[i])return ('+'==a.vorzeichen)?false:true;;
    			}
    			//char a[10]  V1.a[2]				char *a  V2->a[2]
    			return false;
    		}
    
    int main()
    {
    	BigInt b1(100), b2(1),b3(-5245453),b4("  +221234567"), b5=b4;
    	//b1.print();
    	//if (b1<b2)
    	b2=b1+b2;
    	b2.print();
    	b2=b2+b2;
    	b2.print();
    	cout<<endl;
    	system("Pause");
    }
    


  • gelöscht


  • Mod

    Fanati_C schrieb:

    for(i=0; (op1.len>op2.len)?op1.len:op2.len; i++)
    

    Ich sehe nicht, wie diese Schleife terminieren könnte. Da du diesen Wert öfter brauchst, solltest du ihn vielleicht nur einmal berechnen und in einer Variablen speichern. Das fördert auch die Lesbarkeit.

    if(op1.len<i)
    

    Diese Abfrage könnte man vor die Schleife ziehen und so Duplizität vermeiden. Du könntest zum Beispiel eine Referenz initialisieren, die auf das längere Objekt zeigt, und in Folge die Referenz statt direkt op1 bzw, op2 zu benutzen.

    BigInt addiere(BigInt op1, BigInt op2)
    

    Da diese Funktion kein this benötigt, gibt es keinen Grund, sie als Memberfunktion (höchstens evtl. static zu definieren).

    BigInt &operator+(const BigInt &a)
        {
            return addiere(*this, a);
        }
    

    Hier warnt der Compiler zurecht. Erstens ist das kein legales C++ und zweitens - selbst wenn es legal wäre, kannst du mit dem Funktionsergebnis nichts anfangen. Das Bigint-Objekt, das addieren (richtigerweise) zurück gibt, wird beim Verlassen der Funktion zerstört, die Referenz darauf damit ungültig.

    Schließlich hast du ein Speicherleck und Objekte werden nicht korrekt kopiert, mit unschönen Folgen. Es müssen noch Kopierkonstruktor, Zuweisungsoperator und Destruktor implementiert werden, weil dein Objekt einen rohen Zeiger auf Speicher, der zwischen verschiedenen Objekten nicht geteilt werden sollte, verwendest.

    Es ist möglich, ohne > zu verwenden, über ein halboffenes Interval rückwärts zu iterieren

    for (i=len;i!=0;)
    {
        --i;
        ... Code
    }
    

    Diese Form ist allgemeiner und auch leicht als korrekt erkennbar.



  • problem gelöst

    das mit dem return aus dem überladenen operator war wirklich nicht gut ^^
    hab ich dann mit hilfe einer memberfunkton mal schnell (aber nicht so schön) ma gelöst, und die for schleife im addiere is ne endlosschleife (ich depp hab das nicht gesehn)

    danke für eure hilfe, vorallem großer dank an dich camper

    Fanati_C


  • Mod

    Es könnte z.B. ungefähr so aussehen:

    BigInt addiere(const BigInt& op1, const BigInt& op2)
        {
            const BigInt& smaller = op1.len < op2.len ? op1 : op2;
            const BigInt& larger = op1.len < op2.len ? op2 : op1;
            BigInt erg(0);
            erg.len = larger.len + 1;
            erg.zahl = new char[ erg.len ];
            erg.vorzeichen = '+';
            int carry = 0;
            int pos = 0;
            for ( ; pos < smaller.len; ++pos )
            {
                carry += larger.zahl[ pos ] + smaller.zahl[ pos ];
                erg.zahl[ pos ] = carry % 10;
                carry /= 10;
            }
            for ( ; pos < larger.len; ++pos )
            {
                carry += larger.zahl[ pos ];
                erg.zahl[ pos ] = carry % 10;
                carry /= 10;
            }
            erg[ pos ] = carry;
            return erg;
        }
    


  • cool, danke nochmal camper, das is eine super lösung, vielen vielen dank dir nochmal :-)))

    zeile 23, erg.zahl[pos] = carry; da hast das zahl vergessen, aber das is net wichtig, funktioniert sehr gut 🙂


Anmelden zum Antworten