Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.net  
   

Die mobilen Seiten von c++.net:
https://m.c-plusplus.net

  
C++ Forum :: C++ (alle ISO-Standards) ::  Stack overflow: bei der Verwendung einer Funktion in der Klasse     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
lucky_daughter
Mitglied

Benutzerprofil
Anmeldungsdatum: 10.11.2017
Beiträge: 11
Beitrag lucky_daughter Mitglied 01:01:32 12.01.2018   Titel:   Stack overflow: bei der Verwendung einer Funktion in der Klasse            Zitieren

Hallöchen, bin neu in der Thema, wie man eigene Klasse erstellt usw. und bin fast sicher, dass der Fehler auf der Oberfläche liegt, hab selbst im Internet nachgegugt und nix gefunden.. Wahrscheinlich verstehe ich was nicht ganz klar und stelle falsche Fragen zu Google.

Hier geht es um ne Klasse, die eine Zahl modulo 13 speichert, dabei muss der Parameter, der übergeben wirt unsigned int sein. Dann überlade ich einige Operatoren und im Falle wenn eine Zahl der Klasse (minus/ mal) eine negative Zahl gerechnet wird kommt schliesslich ne negative Zahl raus und der Zahl muss wieder ensprechende Restklasse(mod 13) zugewiesen werden, deswegen habe ich ne Methode verwendet, die ihr übergebene Zahl in die Restklasse(13) verschiebt : (z.b aus -3 -> +10 macht).


Soweit ich eine Methode (also void-Funktion)verwendet habe (Code unten) funktionirte alles, danach wollte ich meinen Code ein bisschen schöner gestalten, deswegen habe ich die als eine Funktion überschrieben: (und genau dann ist der Fehler aufgetreten! )



Der Fehler: Ausnahmefehler bei 0x010B1879 in ZahlModulo13.neu.exe: 0xC00000FD: Stack overflow (Parameter: 0x00000001, 0x010D2F58),
sowie ich das verstehe: Stack overflow passiert wenn Rekursion sehr oft auftritt oder wenn man auf Speicher zugreift, der gar nicht existiert, was mache ich da falsch?



Ich wäre sehr dankbar wenn ihr mir helfen würden:


C++:
void restklasse(int n&)
{
        n=((n % 13)+ 13) % 13;
}



C++:
unsigned int restklasse(int n)
{
    return ((n % 13) + 13) % 13;
}


Der ganze Code:

class.h :

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#pragma once
#include<iostream>
class ZahlModulo13
{
public:
    ZahlModulo13(unsigned int n)
    {
        m_n = n % 13;
    };
 
    ZahlModulo13() : m_n(0) {};
 
    friend unsigned int restklasse(int k);
 
    friend ZahlModulo13 operator*(const ZahlModulo13& lhs, int rhs);
    friend ZahlModulo13 operator*(const ZahlModulo13& lhs, const ZahlModulo13& rhs);
    friend ZahlModulo13 operator*(int lhs, const ZahlModulo13& rhs);
 
    friend ZahlModulo13 operator+(const ZahlModulo13& lhs, int rhs);
    friend ZahlModulo13 operator+(const ZahlModulo13& lhs, const ZahlModulo13& rhs);
    friend ZahlModulo13 operator+(int lhs, const ZahlModulo13& rhs);
 
 
    friend ZahlModulo13 operator-(const ZahlModulo13& lhs, int rhs);
    friend ZahlModulo13 operator-(const ZahlModulo13& lhs, const ZahlModulo13& rhs);
    friend ZahlModulo13 operator-(int lhs, const ZahlModulo13& rhs);
 
    friend std::ostream &operator<<(std::ostream &ostr, const ZahlModulo13 &a);
    friend std::istream &operator >> (std::istream &istr, const ZahlModulo13 &a);
 
private:
    unsigned int m_n;
 
};



class.cpp :
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include<iostream>
#include<math.h>
#include"class.h"
 
 
 
unsigned int restklasse(int n)
{
    return ((n % 13) + 13) % 13;
}
 
 
ZahlModulo13 operator*(const ZahlModulo13& lhs, const ZahlModulo13& rhs)
{
    return lhs.m_n * rhs.m_n;
}
 
ZahlModulo13 operator*(const ZahlModulo13& lhs, int rhs)
{
    return ZahlModulo13(lhs.m_n* restklasse(rhs));
}
 
ZahlModulo13 operator *(int lhs, const ZahlModulo13& rhs)
{
    return ZahlModulo13(rhs.m_n* restklasse(lhs));
}
 
 
ZahlModulo13 operator+(const ZahlModulo13& lhs, const ZahlModulo13& rhs)
{
    return ZahlModulo13(lhs.m_n + rhs.m_n);
}
 
ZahlModulo13 operator +(const ZahlModulo13& lhs, int rhs)
{
    return ZahlModulo13(lhs.m_n + restklasse(rhs));
}
 
ZahlModulo13 operator +(int lhs, const ZahlModulo13& rhs)
{
    return ZahlModulo13(rhs.m_n + restklasse(lhs));
}
 
ZahlModulo13 operator - (const ZahlModulo13& lhs, const ZahlModulo13& rhs)
{
return ZahlModulo13( restklasse(lhs.m_n - rhs.m_n));
}
 
ZahlModulo13 operator - (const ZahlModulo13& lhs, int rhs)
{
return  ZahlModulo13( restklasse(lhs.m_n - rhs));
}
 
ZahlModulo13 operator -(int lhs, const ZahlModulo13& rhs)
{
return  ZahlModulo13( restklasse(lhs - rhs.m_n));
}
 
 
 
std::ostream &operator<<(std::ostream &ostr, const ZahlModulo13 &a)
{
    ostr << a.m_n;
    return ostr;
}
 
std::istream &operator >> (std::istream &istr, const ZahlModulo13 &a)
{
    istr >> a.m_n;
    return istr;
}


Main.cpp :

C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include<iostream>
#include"class.h"
 
int main()
{
    ZahlModulo13 a, b, erg;
    char c;
 
    std::cout << "Geben Sie Ihre erste Zahl ein: ";
    std::cin >> a;
 
    std::cout << "Geben Sie Ihre zweite Zahl ein: ";
    std::cin >> b;
 
    std::cout << "Geben Sie ein Operator ein (+,-,*): ";
    std::cin >> c;
 
    switch (c)
    {
    case '+':
        erg = a + b;
        break;
    case '*':
        erg = a * b;
        break;
    }
 
    std::cout << "In der Restklasse 13: a " << c << " b = " << a << "(13) " << c << b << "(13) = " << erg << "(13) ";
 
    std::cin.get();
    return 0;
}
manni66
Mitglied

Benutzerprofil
Anmeldungsdatum: 30.11.2017
Beiträge: 270
Beitrag manni66 Mitglied 01:09:35 12.01.2018   Titel:              Zitieren

Dann schaust du mal mit dem Debugger nach, in welcher Funktion der Stack überläuft.
MFK
Mitglied

Benutzerprofil
Anmeldungsdatum: 02.11.2002
Beiträge: 5982
Beitrag MFK Mitglied 08:32:20 12.01.2018   Titel:              Zitieren

Der operator>> ruft sich selbst auf.

Du hast a als const& deklariert, also kann dieser Operator a (und damit auch a.m_n) nicht ändern. Er kann aber aus a.m_n ein temporäres ZahlModulo13 bauen und dessen operator>> (also sich selbst) aufrufen.

_________________
"Funktioniert nicht" ist keine ausreichende Fehlerbeschreibung.
wob
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.05.2017
Beiträge: 396
Beitrag wob Mitglied 10:53:22 12.01.2018   Titel:              Zitieren

...und um zu verhindern, dass ungewünscht der Konstruktor aufgerufen wird, solltest du im Normalfall alle Konstruktoren, die nur ein Argument haben, als explicit deklarieren.

Also:
C++:
explicit ZahlModulo13(unsigned int n) {
   ...
}


Dann fällt auch auf, dass dein operator* einfach nur eine Zahl zurückgibt. Auch hier musst du dann explizit "ZahlModulo13" schreiben, wie in den anderen Operatoren auch.

Achtung bei modulo mit negativen Zahlen, wenn dein Code vor C++11 laufen soll - dann ist das Ergebnis nämlich nicht vom Standard festgelegt, sondern implementierungsabhängig. Ich bekomme bei Modulo mit Negativen Zahlen sowieso immer einen Knoten in den Kopf, also empfehle ich hier, unbedingt ein paar Tests zu schreiben!
lucky_daughter
Mitglied

Benutzerprofil
Anmeldungsdatum: 10.11.2017
Beiträge: 11
Beitrag lucky_daughter Mitglied 14:18:37 13.01.2018   Titel:              Zitieren

MFK schrieb:
Der operator>> ruft sich selbst auf.

Du hast a als const& deklariert, also kann dieser Operator a (und damit auch a.m_n) nicht ändern. Er kann aber aus a.m_n ein temporäres ZahlModulo13 bauen und dessen operator>> (also sich selbst) aufrufen.


Ah, stimmt! Danke für den Tipp :)
lucky_daughter
Mitglied

Benutzerprofil
Anmeldungsdatum: 10.11.2017
Beiträge: 11
Beitrag lucky_daughter Mitglied 14:31:51 13.01.2018   Titel:              Zitieren

wob schrieb:
...und um zu verhindern, dass ungewünscht der Konstruktor aufgerufen wird, solltest du im Normalfall alle Konstruktoren, die nur ein Argument haben, als explicit deklarieren.

Also:
C++:
explicit ZahlModulo13(unsigned int n) {
   ...
}


Dann fällt auch auf, dass dein operator* einfach nur eine Zahl zurückgibt. Auch hier musst du dann explizit "ZahlModulo13" schreiben, wie in den anderen Operatoren auch.

Achtung bei modulo mit negativen Zahlen, wenn dein Code vor C++11 laufen soll - dann ist das Ergebnis nämlich nicht vom Standard festgelegt, sondern implementierungsabhängig. Ich bekomme bei Modulo mit Negativen Zahlen sowieso immer einen Knoten in den Kopf, also empfehle ich hier, unbedingt ein paar Tests zu schreiben!


Bei dem Operator* hab ich noch getestet und ist egal, ob ich das Ergebnis in ZahlModulo13 umwandle oder nicht: Funktion erwartet den entsprechenden Typ und macht's selbst. Oder ist es einfach 'schöner' zu lesen?

Und ja, danke für den Tipp mit dem expliziten Konstrktor, das wusste ich nicht:)
C++ Forum :: C++ (alle ISO-Standards) ::  Stack overflow: bei der Verwendung einer Funktion in der Klasse   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.net ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.