C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Speicherzugriffsfehler

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Georg Maaß
Guest





PostPosted: Sat May 29, 2004 3:23 pm    Post subject: Speicherzugriffsfehler Reply with quote



Wie kann man ohne Zeiger zu reproduzierbaren Speicherzugriffsfehlern kommen?

Bereits das Werfen von einer meiner Exceptions kann das Phänomen
auslösen. Wenn sie von std::exception ableitet sind, löst es sogar
garantiert dieses Phänomen aus. Der Destruktor von std::exception ist
virtuell. Das kann es also nicht sein. Auch hat die Beseitigung des
Fehlers, daß die Destruktoren meiner eigenen Exceptions trotz deren
polymorphen Einsatzes nicht virtuell waren, nichts an dem Problem
geändert. Die Speicherzugriffsfehler treten immer noch auf.

Das Problem tritt jedoch nicht nur in Zusammenhang mit meinen Exceptions
auf, sondern auch mit dem Zugriff auf public Members anderer mehrstufig
abgeleiteter polymorpher Klassen auf. Auch dort sind die Destruktoren
virtuell.

Da keine Zeiger verwendet werden, sondern ausschließlich Referenzen,
kann es keine fehlerhafte Zeigerarthritis sein. Ob es überhaupt
irgendwie mit Polymorphie zusammenhängt, ist mir unklar. Da ich einfach
keine Idee mehr habe, was es sein könnte.

http://gml-modul.sourceforge.net/docu/c++SourceReader.php3?url=/3/Application.c++#crash1

Die Ausgabe sieht so aus:

georg@stroh:~> ~/gmL/3.x/bin/sampleserver
SIGINT: 0 SIG_IGN: 1 SIG_DFL: 0
SIGINT: handler installed (1,0)
SIGHUP: 0 SIG_IGN: 1 SIG_DFL: 0
SIGHUP: handler installed (1,0)
SIGUSR1: 0 SIG_IGN: 1 SIG_DFL: 0
SIGUSR1: handler installed (1,0)
Anzahl Typen: 23
gm::Application::Application(AppService& theService) started...
gm::Application::Application(AppService& theService) service name found...
gm::Application::Application(AppService& theService)
Application::getServerSocketConfiguration().socketPath = /var/tmp/gmL/
gm::Application::Application(AppService& theService)
theService.serv/var/tmp/gmL/0Pp�°Ðð0Pp�°1Speicherzugriffsfehler

Das Zeug bis "Anzahl Typen 23" wird von main ausgegeben. Danach wird
dort eine lokale Variable mit einer von AppService abgeleitenen Klasse
initialisiert. Anschließend wird eine lokale Application-Variable
intialisiert, wobei eine Referenz auf die erste Variable als Argument an
den Konstruktor übergeben wird. Hier das entsprechende Stück aus main:

sampleserverService sampleService ("banana"); // We provide a sample
service named "banana"
gm::Application application(sampleService); // tell the application
which service we provide

So wie der Quelltext gerade im Netz liegt, tritt keine Exception auf,
sondern der Zugriff auf das public Member theService.servicename löst
den SEGFAULT aus.

Wahrscheinlich habe ich irgendwas Banales kapital falsch gemacht. Ich
habe aber keinen Schimmer, was das ist.

Gruß, Georg
--
Georg Maaß - bioshop.de D-76227 Karlsruhe, Westmarkstraße 82
HTML, XML / JavaScript, C++, Java, PHP, VB / CGI, JSP, ASP, ASP.net
- The ultimate DHTML engine: http://gml-modul.sourceforge.net -
http://sourceforge.net/projects/gml-modul

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Georg Maaß
Guest





PostPosted: Sat May 29, 2004 6:08 pm    Post subject: Re: Speicherzugriffsfehler Reply with quote



Georg Maaß wrote:
Quote:
sampleserverService sampleService ("banana"); // We provide a sample
service named "banana"

Das hier ist der Übeltäter, denn sampleService ist von AppService
abgeleitet und verwendet nachfolgenden Konstruktor:

public: class AppService : protected virtual basic_AppService
{
public:
const std::string& servicename;
AppService(const std::string& Servicename)throw
():servicename(Servicename){};

[...]
}

Da hier eine Übergabe per Referenz erfolgt und intern nur die Referenz
abegespeichert wird, der referenzierte std::string aber offenbar nur
temporär während des Aufrufs von sampleService ("banana") existiert und
nicht wie erwartet solange, wie es die Variable sampleService gibt, ist
die Referenz auf den String spätestens beim Erreichen des Semikolons
ungültig.

Referenzen sind also noch gefährlicher als Zeiger, weil sie einen in
falscher Sicherheit wiegen. Man lebt halt referentiell gefährlich...
--
Georg Maaß - bioshop.de D-76227 Karlsruhe, Westmarkstraße 82
HTML, XML / JavaScript, C++, Java, PHP, VB / CGI, JSP, ASP, ASP.net
- The ultimate DHTML engine: http://gml-modul.sourceforge.net -
http://sourceforge.net/projects/gml-modul

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Horst Kraemer
Guest





PostPosted: Sun May 30, 2004 10:03 am    Post subject: Re: Speicherzugriffsfehler Reply with quote



On Sat, 29 May 2004 20:08:48 +0200, Georg Maa <georg (AT) bioshop (DOT) de>
wrote:

Quote:
Georg Maa wrote:
sampleserverService sampleService ("banana"); // We provide a sample
service named "banana"

Das hier ist der beltter, denn sampleService ist von AppService
abgeleitet und verwendet nachfolgenden Konstruktor:

public: class AppService : protected virtual basic_AppService
{
public:
const std::string& servicename;
AppService(const std::string& Servicename)throw
():servicename(Servicename){};

[...]
}

Da hier eine bergabe per Referenz erfolgt und intern nur die Referenz
abegespeichert wird, der referenzierte std::string aber offenbar nur
temporr whrend des Aufrufs von sampleService ("banana") existiert und
nicht wie erwartet solange, wie es die Variable sampleService gibt, ist
die Referenz auf den String sptestens beim Erreichen des Semikolons
ungltig.

Referenzen sind also noch gefhrlicher als Zeiger, weil sie einen in
falscher Sicherheit wiegen. Man lebt halt referentiell gefhrlich...

Stimmt. Hiermit oder mit dem naechsten Beispiel erzeugst Du einen
huebschen segfault:

#include <string>
#include <iostream>
using namespace std;

struct X
{
const string& s;
X(const string& s_): s(s_) {}
};


int main()
{
cout << X("Hallo").s << endl; // OK
X x("Hallo");
cout << x.s << endl; // crash

return 0;
}

================================

const string& f()
{
const string& r = "Hallo";
return r;
}

int main()
{
const string& s = f();
cout << s << endl; // crash
}


Fuer die Lebenszeit eines Temporaries ist die Referenz entscheidend,
an die das Temporary *direkt* gebunden wird (bzw. der Ausdruck, in dem
das Temporary vorkommt). Die Lebenszeit wird nicht dadurch
verlaengert, dass die an das Temporary gebundene Referenz an eine
Referenz mit laengerer Lebensdauer weitergereicht wird. So etwas waere
ohne gargabe collection schwer zu realisieren.

--
Horst

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Markus Breuer
Guest





PostPosted: Sun May 30, 2004 12:57 pm    Post subject: Re: Speicherzugriffsfehler Reply with quote

Georg Maaß wrote:

Quote:
Georg Maaß wrote:

Da hier eine Übergabe per Referenz erfolgt und intern nur die Referenz
abegespeichert wird, der referenzierte std::string aber offenbar nur
temporär während des Aufrufs von sampleService ("banana") existiert und
nicht wie erwartet solange, wie es die Variable sampleService gibt, ist
die Referenz auf den String spätestens beim Erreichen des Semikolons
ungültig.

Referenzen sind also noch gefährlicher als Zeiger, weil sie einen in
falscher Sicherheit wiegen. Man lebt halt referentiell gefährlich...

Aber das ist kein Problem von Referenzen, mit einem Zeiger wäre das
Objekt ebenso ungültig gewesen. Der eigentliche Fehler ist das
Temporary, das nur innerhalb des Ausdrucks existiert.
Wenn deine Funktion einen Zeiger auf eine lokale Variable zurück gibt,
ist das auch nicht die Schuld des Pointers.

Gruß Markus

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.