Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Programm-amoklauf bei Vector

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
20.10.2003, 11:17 Uhr
~Craven
Gast


Servus.

Folgendes Problem: Ich habe eine Klasse als Datenbehälter gebaut, sprich sie besitzt als Attribut ein "void *", mit set- und get-Methoden. Dort werden unterschiedliche Werte eingetragen. D.h. mal

1. vector<float*> *valuefloat;
2. vector<CombinedDataTypeStruct*> *valuestruct;
3. float *f;

die dort eingetragen werden. Ich weis (durch Merken einer zusätzlichen Variable), ob es sich um 1,2 oder 3 handelt, caste es also hinterher entsprechend.

Bei normalen Floats (kein Vector!) habe ich keine Probleme, nur sobald ich z.B. 512 mal CombinedDataTypeStructs in den Vector packen will (Combined..Struct beinhaltet wiederum zwei void*, normalerweise Zeiger auf float und int) ... scheint das Programm Amok zu laufen und stürzt regelmäßig mit "Speicherzugriffsfehler" ab. Muss ich unter Linux (bitte nicht wieder in das Linux-Board verschieben ) da irgendwie noch was mit der Speicherverwaltung beachten??

Zum besseren Verständnis (das Programm ist ca. 5000 Zeilen lang, wäre also etwas zu viel, um es zu posten): Klasse A erzeugt mit new die oben genannten Structs, mit new werden auch Zeiger auf floats und ints gesetzt, die Zeiger im Struct belegt, dann entsprechend in einen (mit new erzeugten) Vector gepackt und der Zeiger an die Klasse B (Datenbehälter) mit setData(void* data) übergeben. Wichtig dabei: Von Klasse A wird keines der erzeugten Objekte mit delete gelöscht!! Das erfolgt in Klasse C, die die Daten wieder herausholt. Zum einen ist dann der Vector wesentlich größer geworden (5131 oder so, anstelle von 512; beim Abfrage der Vectorlänge in der set-methode ist die Länge noch in Ordnung, auch die Belegung des Attributs in der Klasse, bei der get-Methode nicht mehr) .... und dann stürzt das Programm an Stellen ab, an denen es nicht abstürzen dürfte. Das ganze läuft in einer statischen Lib ab. Ich vermute da irgendwo Probleme mit der Speicherverwaltung, bin mir aber nicht sicher.

Ich hoffe, ich habe das halbwegs verständlich rüberbringen können. Hat einer eine Ahnung, wo das Problem liegt?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
20.10.2003, 12:15 Uhr
virtual
Sexiest Bit alive
(Operator)


Das hat weniger was mit Linux als mit krankem Design zu tun. Solche Variablen, die sich merken, welche Variante in einer Struktur die aktive ist (auch diskriminator genannt) sind ziemlich schwer zu warten und fehleranfällig (was Du ja zu spüren bekommst). Ich kann dir mangels Source nicht weiterhelfen. Nur die Empfehlung asusprechen, noch mal zu überlegen, ob Du nicht einfach wirklich C++ programmieren willst und diese Diskriminator Relikte aus C über Bord werfen willst.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
20.10.2003, 21:43 Uhr
0xdeadbeef
Gott
(Operator)


Das ist ja fast so bösartig wie diese Variants. Kannst du an der Stelle keine templates benutzen?
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
21.10.2003, 10:47 Uhr
~Craven
Gast


Ja ja, schön und gut, aber das ist nicht unser Problem.

Wir haben ein Speicherzugriffsproblem und zwar passiert das, sobald ich das Ding mit new initialisiere, stürzt das Programm mit Speicherzugriffsfehler ab.

Deklaration in Header-Datei:
vector<CombinedDataTypeStruct*> *valuestruct;

Im Programmcode:
...
this->valuestruct = new vector<CombinedDataTypeStruct*>;
...

Und genau da stürzt er ab. Ich habe schon Alternativ dazu geschrieben, indem ich anstelle des Vectors eine Klasse erstellt habe...

class DataContainerA {
private :
vector<float> *werte;
vector<unsigned long> *errors;
public :
// De- und Konstruktor
DataContainerA() {
werte = new vector<float>;
errors = new vector<unsigned long>;
};
~DataContainerA() {
....
}

d.h. diesmal keine Zeiger auf die floats und longs, sondern direkt die Werte. Initialisiert wird das dann mit
..
valuestruct_a = new QLSDataContainerAna();
...

Wieder stürzt er an derselben Stelle ab!!! Es wird einfach nur zu Beginn neu gebaut und es existieren noch nicht einmal sonstige Referenzen auf das Objekt. Gibt es für Module irgendeine Art Speicherbegrenzung???
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
21.10.2003, 11:41 Uhr
~Craven
Gast


Nachtrag:

Es muss definitiv eine Art Speicherüberlauf sein (obwohl laut System-Monitor nur 1,5 MB dauerhaft belegt sind). Sobald ich das new (und die späteren Zugriffe auf das Objekt auskommentiere) bleibt er beim nächsten Anlegen eines größeren Objektes mit new hängen!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
21.10.2003, 12:51 Uhr
virtual
Sexiest Bit alive
(Operator)



C++:
#include <stdlib.h>

int main()
{
    char* m;
    free(m);
}

st Du dir davor irgendwo - bereits vor dem new - den Speicher zerhauen. Compiler den Kram mal Debuginfos und lass es nach mit dem valgrind laufen. Ist ein ziemlich gutes Mittel, um unter Linux Speicherprobleme auf den grund zu gehen. Einfach

Code:
valgrind <program> <program-parameter>
[/cpp]
eingeben, zB folgendes falsche Program:
||CPP||
Produziert mit valgrind diesen Output:

Code:
23 $ gcc -ggdb a.c  
24 $ valgrind a.out
==18567== valgrind-1.0.4, a memory error detector for x86 GNU/Linux.
==18567== Copyright (C) 2000-2002, and GNU GPL'd, by Julian Seward.
==18567== Estimated CPU clock rate is 1005 MHz
==18567== For more details, rerun with: -v
==18567==
==18567== Conditional jump or move depends on uninitialised value(s)
==18567==    at 0x4004921C: free (vg_clientfuncs.c:177)
==18567==    by 0x8048422: main (a.c:6)
==18567==    by 0x40272BAF: __libc_start_main (in /lib/libc.so.6)
==18567==    by 0x8048331: free@@GLIBC_2.0 (in /home/jhampel/tmp/a.out)
==18567==
==18567== Invalid free() / delete / delete[]
==18567==    at 0x40049272: free (vg_clientfuncs.c:180)
==18567==    by 0x8048422: main (a.c:6)
==18567==    by 0x40272BAF: __libc_start_main (in /lib/libc.so.6)
==18567==    by 0x8048331: free@@GLIBC_2.0 (in /home/jhampel/tmp/a.out)
==18567==    Address 0xBFFFF378 is not stack'd, malloc'd or free'd
==18567==
==18567== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
==18567== malloc/free: in use at exit: 0 bytes in 0 blocks.
==18567== malloc/free: 0 allocs, 1 frees, 0 bytes allocated.
==18567== For a detailed leak analysis,  rerun with: --leak-check=yes
==18567== For counts of detected errors, rerun with: -v


Ich habe damit schon mehrere Bugs erlegt und es ist ziemlich zuverlässig, besser jedenfalls als so Sachen wie purify (was ja auch noch richtig teuer ist!)
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: