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 

Problem mit valarray

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





PostPosted: Wed Apr 26, 2006 7:49 pm    Post subject: Problem mit valarray Reply with quote



Hallo Leute,

ich habe folgendes Problem.

Ich habe mir eine eigene Datenstruktur aus verschachtelten valarray
zusammengebaut. Diese werden erfolgreich initalisiert und mit leben
gefüllt. Das Problem ist, daß beim Aufruf von cshift, das Programm einen
Segfault wirft.

Mittels Debugging habe ich herausgefunden, daß der Fehler bei der ersten
Rotieren in einer unter Schleife auftritt. Der Fehlermeldung ist folgende:
std::__valarray_release_memory (__p=0x8605bf8) at valarray_array.h:71
71 { operator delete(__p); }

dabei wird hier compilerspezifisch ein "glibc detected *** free()" geworfen.

Zum Code (wichtiger Teil):

Localisation.h:

typedef std::valarray<double> Phi;
typedef std::valarray<Phi> Plane;
typedef std::valarray<Plane> GridWorld;

class Localisation
{
/*snip*/
private:
GridWorld gridWorld;
/*snip*/
}

Das Problem tritt auf bei folgendem Aufruf in einer Methode der Klasse:

void update()
{
for(int i = 0; i < this->gridX; i++)
{
for(int j = 0; j < this->gridY; j++)
{
std::cout << j << " ";
this->gridWorld[i][j] = this->gridWorld[i][j].cshift(deltaPhi); /*
DER ERSTE DURCHLAUF BRINGT PROBLEM SCHON */
}
std::cout << std::endl << i << " ";
this->gridWorld[i] = this->gridWorld[i].cshift(yshift);
}
this->gridWorld = this->gridWorld.cshift(xshift);
}

Was mich wundert, ist daß in einem kleinen mini-Beispiel ausprobiert
folgendes funktioniert ohne Probleme:


typedef std::valarray<double> Phi;
typedef std::valarray<Phi> Plane;
typedef std::valarray<Plane> GridWorld;


std::cout << "init des valarrays" << std::endl;

GridWorld grid;
grid.resize(5);

for(int i = 0; i < 5 ; i++)
{
grid[i].resize(5);

for(int j = 0; j < 5 ; j++)
{
grid[i][j].resize(1Cool;
}
}

for(int i = 0; i < 5; i++)
{
for(int j = 0; j < 5; j++)
{
for(int k=0; k < 18; k++)
{
grid[i][j][k] = i+j+k;
}
}
}

std::cout << "Ausgabe: " << std::endl;
for(int i = 0; i < 5; i++)
{
for(int j=0; j < 5; j++)
{
for(int k=0; k < 18; k++)
{
std::cout << grid[i][j][k] << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
}
std::cout << std::endl;

std::cout << "Nach shift: " << std::endl;
for(int i = 0; i < 5; i++)
{
for(int j=0; j < 5; j++)
{
grid[i][j] = grid[i][j].cshift(3);
}
grid[i] = grid[i].cshift(2);

}
grid = grid.cshift(1);
for(int i= 0; i < 5; i++)
{
for(int j = 0; j < 5 ; j++)
{
for(int k=0; k < 18; k++)
{
std::cout << grid[i][j][k] << " " ;
}
std::cout << std::endl;
}
std::cout << std::endl;
}
std::cout << std::endl;

Ich denke mal, daß es ein Fehler in meinem Code ist, denn ich kann mir
nicht vorstellen, daß in den C-libs fehler sein könnten.

Wäre dankbar, wenn mich einer auf das Problem stoßen könnte, warum das
so nicht geht.

Danke für Eure Hilfe.

Gruß

Alexander

--
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
Torsten Robitzki
Guest





PostPosted: Wed May 03, 2006 4:08 pm    Post subject: Re: Problem mit valarray Reply with quote



Alexander Camek wrote:
Quote:
Hallo Leute,

Hallo Alexander
Quote:
ich habe folgendes Problem.

Ich habe mir eine eigene Datenstruktur aus verschachtelten valarray
zusammengebaut. Diese werden erfolgreich initalisiert und mit leben
gefüllt. Das Problem ist, daß beim Aufruf von cshift, das Programm einen
Segfault wirft.

Mittels Debugging habe ich herausgefunden, daß der Fehler bei der ersten
Rotieren in einer unter Schleife auftritt. Der Fehlermeldung ist folgende:
std::__valarray_release_memory (__p=0x8605bf8) at valarray_array.h:71
71 { operator delete(__p); }

dabei wird hier compilerspezifisch ein "glibc detected *** free()"
geworfen.

Zum Code (wichtiger Teil):

Localisation.h:

typedef std::valarray<double> Phi;
typedef std::valarray<Phi> Plane;
typedef std::valarray<Plane> GridWorld;

class Localisation
{
/*snip*/
private:
GridWorld gridWorld;
/*snip*/
}

Das Problem tritt auf bei folgendem Aufruf in einer Methode der Klasse:

void update()
{
for(int i = 0; i < this->gridX; i++)
{
for(int j = 0; j < this->gridY; j++)
{
std::cout << j << " ";
this->gridWorld[i][j] =
this->gridWorld[i][j].cshift(deltaPhi); /* DER ERSTE DURCHLAUF BRINGT
PROBLEM SCHON */
}
std::cout << std::endl << i << " ";
this->gridWorld[i] = this->gridWorld[i].cshift(yshift);
}
this->gridWorld = this->gridWorld.cshift(xshift);
}

Was mir als erstes auffällt ist: Wozu das "this->" und warum testest Du
die Laufvariablen nicht gegen die Größe der arrays sondern gegen externe
variablen? Läßt sich das reproduzieren? Wenn ja, was passiert, wenn du
mit asserts sicher stellst, das i und j einen gültigen Wert haben. Was
passiert, wenn die deltaPhi = 0 setzt. Was passiert wenn Du den
gezeigten code durch:
gridWorld[i][j] = gridWorld[i][j]; oder
gridWorld[i][j] = Phi(gridWorld[i][j]);
ersetzt. Die einzige Stelle, in der delete gerufen wird, ist wohl das
Zerstören des temporären Objekts am Ende des Ausdrucks. Hast Du den Wert
von __p? Ist es ein nahe bei 0 Wert?

Quote:

Was mich wundert, ist daß in einem kleinen mini-Beispiel ausprobiert
folgendes funktioniert ohne Probleme:

Das spricht meist dafür, das der Fehler nicht im Kodebeispiel ist,
sonder vorher der heap schon korrumpiert ist.

Quote:
Ich denke mal, daß es ein Fehler in meinem Code ist, denn ich kann mir
nicht vorstellen, daß in den C-libs fehler sein könnten.

Die C-libs sind meist schon älter und damit besser getestet, bei den C++
Bibliotheken findet man bestimmt hin und wieder noch mal einen Fehler.

Ansonsten gibt es Tools, mit denen man kaputtem Freispeicher auf die
Schliche kommt.

mfg Torsten

--
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
Alexander Camek
Guest





PostPosted: Thu May 04, 2006 2:59 pm    Post subject: Re: Problem mit valarray Reply with quote



Hi Thorsten,

Quote:
ich habe folgendes Problem.

Ich habe mir eine eigene Datenstruktur aus verschachtelten valarray
zusammengebaut. Diese werden erfolgreich initalisiert und mit leben
gefüllt. Das Problem ist, daß beim Aufruf von cshift, das Programm
einen Segfault wirft.

Mittels Debugging habe ich herausgefunden, daß der Fehler bei der
ersten Rotieren in einer unter Schleife auftritt. Der Fehlermeldung
ist folgende:
std::__valarray_release_memory (__p=0x8605bf8) at valarray_array.h:71
71 { operator delete(__p); }

dabei wird hier compilerspezifisch ein "glibc detected *** free()"
geworfen.


Was mir als erstes auffällt ist: Wozu das "this->" und warum testest Du
die Laufvariablen nicht gegen die Größe der arrays sondern gegen externe
variablen? Läßt sich das reproduzieren?

Ich merke schon, daß ich mich damals falsch ausgedrückt habe. Ich habe
ein Klasse die heißt: Localisation. Diese Klasse besitzt Variablen.

class Localisation
{
private: GridWorld gridWorld;
int gridX;
int gridY;
/* usw. */
}

Okay, ich habe die Funktion wohl mißverständlich hingeschrieben. Sie lautet:
void Localisation::updateOdo()
{
for(int i = 0; i < this->gridX; i++)
{
for(int j = 0; j < this->gridY; j++)
{
std::cout << j << " ";
this->gridWorld[i][j] =
this->gridWorld[i][j].cshift(deltaPhi); /* DER ERSTE DURCHLAUF BRINGT
PROBLEM SCHON */
}
std::cout << std::endl << i << " ";
this->gridWorld[i] = this->gridWorld[i].cshift(yshift);
}
this->gridWorld = this->gridWorld.cshift(xshift);
}

Wozu "this->", weil es klassenvariablen sind. Diese werden aus einer
config-datei eingelesen und dabei auf richtige größe geprüft! Diese
stimmt auch, da ich sonst in einer anderen Methode der Klasse einen
Segfault bekommen würde. Denn dort laufe ich auch jeweils bis zu den
variablen größen "gridX" und "gridY". Außerdem ist es hier Codingsytle
"this->" in Klassen zu verwenden, ist besser lesbarer.

Ich möchte also meine GridWorld jeweils um einen shiftfaktor rotieren
lassen. Da ich keine Informationen verlieren möchte benutze ich cshift.
Der Rückgabewert von cshift is ein neues valarray, dieses möchte ich ja,
deshalb muß ich es auch in meiner Klassenvariable ablegen.

Quote:
gridWorld[i][j] = Phi(gridWorld[i][j]);

Ich weiß nicht was Du damit meinst? Was ist bei Dir diese Methode Phi()?

Quote:
ersetzt. Die einzige Stelle, in der delete gerufen wird, ist wohl das
Zerstören des temporären Objekts am Ende des Ausdrucks. Hast Du den Wert
von __p? Ist es ein nahe bei 0 Wert?

Was meinst Du damit? __p zeigt auf einen Speicherbereich und prüft nicht
den Inhalt, oder hab ich Dich da jetzt falsch verstanden? Selbst wenn
der Speicherinhalt nahe 0 ist, sollte delete das nicht interessieren. Es
dürfte sich nur beschwehren, wenn ich ein Feld außerhalb des allocierten
Speichers für das jeweilige Objekt löschen möchte.

Quote:
Was mich wundert, ist daß in einem kleinen mini-Beispiel ausprobiert
folgendes funktioniert ohne Probleme:


Das spricht meist dafür, das der Fehler nicht im Kodebeispiel ist,
sonder vorher der heap schon korrumpiert ist.

Okay, was ich zwar nicht glaube. Werd dann wohl schauen, wo das genau
korrumpiert wird. Kann auch sein, daß mir da CORBA einen strich durch
die Rechnung macht, aber dies gehört dann in eine andere Newsgroup :)

Quote:
Ich denke mal, daß es ein Fehler in meinem Code ist, denn ich kann mir

nicht vorstellen, daß in den C-libs fehler sein könnten.

Die C-libs sind meist schon älter und damit besser getestet, bei den C++
Bibliotheken findet man bestimmt hin und wieder noch mal einen Fehler.

Neija, aber c++ Bibliotheken werden bestimmt nicht fehlerhaft sein,
vorallem nicht im Bereich der STL. Schließlich arbeiten sehr viele damit
und wenden dies auch an. Wozu gibt es schließlich Bugreports für die
jeweiligen Plattformen ;)

Quote:
Ansonsten gibt es Tools, mit denen man kaputtem Freispeicher auf die
Schliche kommt.

Ich habs auch mit valgrim getestet, aber der findet nix. Wobei wie man
weiß heißt ein erfolgreicher Test nicht, daß es keine Fehler mehr gibt :)

Gruß

Alexander

--
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
Torsten Robitzki
Guest





PostPosted: Thu May 04, 2006 9:23 pm    Post subject: Re: Problem mit valarray Reply with quote

Alexander Camek wrote:

Quote:
Hi Thorsten,

Hi Ahlexander,

Quote:
Was mir als erstes auffällt ist: Wozu das "this->" und warum testest
Du die Laufvariablen nicht gegen die Größe der arrays sondern gegen
externe variablen? Läßt sich das reproduzieren?


Ich merke schon, daß ich mich damals falsch ausgedrückt habe. Ich habe
ein Klasse die heißt: Localisation. Diese Klasse besitzt Variablen.

die Frage, nach dem "wieso this->" war keine Verständnisfrage. Für den
Fall, das sich der Code ohne diesen nicht übersetzen ließe oder andere
Fehler auftreten könnte ein Hinweis auf mögliche Fehlerquellen sein.

Quote:
class Localisation
{
private: GridWorld gridWorld;
int gridX;
int gridY;
/* usw. */
}

Okay, ich habe die Funktion wohl mißverständlich hingeschrieben. Sie
lautet:

<siehe erstes posting>

Was die Funktion machen soll, ist schon klar, tut mir leid, wenn meine
Antwort das nicht hat klar werden lassen.

Quote:
Wozu "this->", weil es klassenvariablen sind.

Meinst Du wirklich Klassenvariablen? Damit würde ich statische Variablen
verbinden und das "this->" als irreführend bezeichnen.

Quote:
Diese werden aus einer
config-datei eingelesen und dabei auf richtige größe geprüft! Diese
stimmt auch, da ich sonst in einer anderen Methode der Klasse einen
Segfault bekommen würde. Denn dort laufe ich auch jeweils bis zu den
variablen größen "gridX" und "gridY".

Nicht zwangsläufig. Bei elementweisem Einfügen wird für einen vollen
Container meist viel mehr, als der Platz für das einzufügende Element
reserviert, so das nach einem Einfügen bei dem neuer Speicher
angefordert wurde, der Griff hinter das letzte Element unbemerkt bleiben
könnte. Beim Kopieren eines Containers (oder bei der Implementierung
einer Funktion wie cshift()) ist die benötigte Größe allerdings bekannt.

Hast Du den mal mit asserts sicher gestellt, das Deine Annahme von der
Beziehung zwischen gridX, gridY und gridWorld.size() und
gridWorld[0].size() stimmen?

Quote:
Außerdem ist es hier Codingsytle
"this->" in Klassen zu verwenden, ist besser lesbarer.

Ok, darauf wäre ich so nicht gekommen ;-)

Quote:
Ich möchte also meine GridWorld jeweils um einen shiftfaktor rotieren
lassen. Da ich keine Informationen verlieren möchte benutze ich cshift.
Der Rückgabewert von cshift is ein neues valarray, dieses möchte ich ja,
deshalb muß ich es auch in meiner Klassenvariable ablegen.

Schon klar. Du hast ein reproduzierbares Problem. Meine
Vorschläge/Fragen zielten nun dahin den Code leicht zu modifizieren, um
zu sehen, ob solche Änderungen das Problem verschwinden lassen, um damit
evtl. Rückschlüsse auf das Problem ziehen zu können.

Quote:
gridWorld[i][j] = Phi(gridWorld[i][j]);


Ich weiß nicht was Du damit meinst? Was ist bei Dir diese Methode Phi()?

typedef std::valarray<double> Phi; // siehe Deine erste Mail

und könnte wenn der Compiler nicht zu schlau ist, einfach dazu führen
das ein ungeändertes temporäres Objekt erzeugt wird. Mir ging es nur
darum mal ein paar Spielmöglichkeiten aufzuzeigen. Weitere wäre: "was
passiert, wenn Du eine Funktion wie cshift() extern zum valarray
implementierst und diese verwendest, hast Du schon mal in die
Implementierung von valarray::cshift() geguckt? Was passiert, wenn Du
die Eingangsdaten aus Deiner Datei änderst (vor allem in den
Dimensionen). Was passiert wenn Du cshift() mal durch shift() ersetzt
.... etc.

Quote:
ersetzt. Die einzige Stelle, in der delete gerufen wird, ist wohl das
Zerstören des temporären Objekts am Ende des Ausdrucks. Hast Du den
Wert von __p? Ist es ein nahe bei 0 Wert?


Was meinst Du damit? __p zeigt auf einen Speicherbereich und prüft nicht
den Inhalt, oder hab ich Dich da jetzt falsch verstanden?

Sehe gerade, das in Deinem ursprünglichen posting (__p=0x8605bf8) steht,
womit sich die Frage wohl erledigt hat.

Quote:
Selbst wenn
der Speicherinhalt nahe 0 ist, sollte delete das nicht interessieren. Es
dürfte sich nur beschwehren, wenn ich ein Feld außerhalb des allocierten
Speichers für das jeweilige Objekt löschen möchte.

Zeiger mit Werten nahe 0 können oftmals einen Hinweis auf
dereferenzierte null-Zeiger sein.

Quote:

Das spricht meist dafür, das der Fehler nicht im Kodebeispiel ist,
sonder vorher der heap schon korrumpiert ist.


Okay, was ich zwar nicht glaube. Werd dann wohl schauen, wo das genau
korrumpiert wird.

Was hast Du den bis dato probiert? Wie sieht den z.B. der komplette
Callstack bis zum delete aus?

Quote:
Die C-libs sind meist schon älter und damit besser getestet, bei den
C++ Bibliotheken findet man bestimmt hin und wieder noch mal einen
Fehler.


Neija, aber c++ Bibliotheken werden bestimmt nicht fehlerhaft sein,
vorallem nicht im Bereich der STL. Schließlich arbeiten sehr viele damit
und wenden dies auch an. Wozu gibt es schließlich Bugreports für die
jeweiligen Plattformen Wink

Wir arbeiten z.Z. mit einem ca. 5 Jahre altem Compiler und in diesen 5
Jahren haben wir locker 10 Fehler in der STL des Compilers gefunden. Von
"string ignoriert den angegebenen allocator", "vector gibt unter
bestimmten Umständen falsche Werte bei deallozieren von Speicher an den
Allocator" über "stringstream macht merkwürdige Sachen ab einer
Puffergröße größer 1k" bis hin zu "lokale Variablen sind unnötiger Weise
als static deklariert". Ist aber unsere Schuld, wer verwendet schon
einen 5 Jahren alten Compiler Wink.

Ich denke mal das valarray exotisch genug ist, um mit unentdeckten
Fehlern rechnen zu können.

mfg
Torsten

--
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
$realname
Guest





PostPosted: Mon May 15, 2006 12:25 pm    Post subject: Re: Problem mit valarray Reply with quote

Hi Torsten,

sorry für die lange Dauer zur Antwort.

Hab den Fehler wohl gefunden. Zumdinest läuft alles jetzt wie gewollt.
Lag wohl daran, daß in die Struktur durch fehlerhafte Berechnungen
meinerseits, NANs eingetragen wurden und diese wohl das
Zerstören verhinderten, bzw. das anlegen des neuen behindert hat.

Zumindest funktinionieren die cshifts nachdem diese problem behoben wurde.

Danke für die Hilfe

Gruß

Alexander

--
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
Alexander Camek
Guest





PostPosted: Tue May 16, 2006 2:23 pm    Post subject: Re: Problem mit valarray Reply with quote

Hi Thorsten,

also es scheint als hätte ich jetzt den Fehler gefunden.
Zumindest läuft es jetzt und der cshift, tut was er tun soll.

Lag wohl daran, daß ich NaN in meiner struktur hatte.
Als ich das gemerkt und behoben hatte, lief es.

Danke für die Hilfe

Gruß

Alexander

--
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.