Absturz bei Zugriff auf Membervariable

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
Leverator
Beiträge: 37
Registriert: Mo Jan 30, 2012 9:28 pm
Wohnort: ::1

Absturz bei Zugriff auf Membervariable

Beitrag von Leverator » Mo Aug 27, 2012 3:05 pm

Hallo zusammen,

bei mir schmiert ein Programm mit einem Segmentationfault ab - was manchmal nicht weiter ungewöhnlich ist - aber in diesem Fall schon, weil der Zugriff auf std::vector-Elemente doch eigenlich vor böser Benutzung geschützt sein sollte.

Hier der Code, welcher innerhalb einer Klasse verwendet wird:

Header:

Code: Alles auswählen

vector< vector<int>* > *dataBuffer;
Konstruktor:

Code: Alles auswählen

dataBuffer = new vector< vector<int>* >;
Prozedur setChannelCount:

Code: Alles auswählen

void DSV::setChannelCount( int count ) {
  int i;
  _channelCount = count;
  maxElementCount = 2^17;      // Maximum 128k Elements per channel
  
  vector<int>	*tmpVec;
  for( i=0; i<_channelCount; i++ ) {
    tmpVec = new vector<int>;
    dataBuffer->push_back( tmpVec );
  }
  dataCounter = 0;
}
Nun stürzt mir das Programm an der Stelle ab, wo in setChannelCount der erste Pointer auf den erzeugten Vektor in den vector*-Vektor gespeichert wird. (Deutsch kann so kompliziert sein...)

ddd meldet beim Versuch dataBuffer zu zeigen, daß er nicht auf die Adresse 0x18 zugreifen könne...
Versteh' ich nicht: Die Datenbereiche sollten doch alle korrekt deklariert worden sein..?

Wer sieht meinen Fehler?


Danke und Gruß,
Lev

Edit by Xin: Titel geändert von "vector< vector<int>* >"

Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

Re: vector< vector<int>* >

Beitrag von fat-lobyte » Mo Aug 27, 2012 3:18 pm

Noch nicht, falls ich noch draufkomme melde ich mich. Aber ne Grundsätzliche Frage:
Wieso Zeiger auf Vektoren von Zeigern auf Vektoren vonInts? Wieso nicht einfach ein Vektor von Vektoren von Ints?

Dafür hat man ja eigentlich std::vector: man muss sich nicht mehr um den Speicher kümmern.

Übrigens tut maxElementCount = 2^17; nicht das was du glaubst. Kuckst du: http://www.proggen.org/doku.php?id=cpp:operator:start

Was außerdem noch sein kann: mit deinen Vektorzugriffen ist alles in Ordnung, aber irgendwas passt mit der Schleife nicht. Welchen Typ hat _channelCount? Warum ist eigentlich count und die Laufvariable i vom Typ "int" und nicht "unsigned" oder "std::size_t"? Es Besteht die Gefahr von Integer-Overflows.
Haters gonna hate, potatoes gonna potate.

Leverator
Beiträge: 37
Registriert: Mo Jan 30, 2012 9:28 pm
Wohnort: ::1

Re: vector< vector<int>* >

Beitrag von Leverator » Mo Aug 27, 2012 3:40 pm

Hi fat-lobyte,

_channelCount ist auch ein int.
Da meine Messkarte zur Zeit höchstens 4 Kanäle simultan ansprechen kann, wäre ein char sogar noch mehr als ausreichend. Also erwarte ich hier keine Integer-Overflows.

Die Variable maxElementCount wird woanders im Code verwendet. Evtl. ist die Definition an dieser Stelle auch unpassend: Vllt. ist der Konstruktor ein besserer Ort dafür.

Ich habe mein Programm in der Zwischenzeit in der Art geändert, wie Du es vorgeschlagen hast.

Code: Alles auswählen

vector< vector<int> > dataBuffer;
Nun startet das ganze Programm erst garnicht.

Witzigerweise funktioniert folgende Prozedur ohne Probleme:

Code: Alles auswählen

void DSV::insertData( const int *data, int size ) {
  int i, j;
 
  // We're using channelCount differend data buffers.
  // They are squentially filled.
#pragma omp parallel for private(i,j)
  for ( i=0; i<size; i+=_channelCount ) {
    for( j=0; j<_channelCount; j++ ) {

// Shift 24-Bit 2's complement code into 32-Bit 2's complement...
// ... and store it into the buffer.
      dataBuffer.at( j ).push_back( (data[i+j]<<8) );
    }
  }

  dataCounter += size/_channelCount;     // update data Counter
  
  if( !dataInUse ) {
    for( i=0; i<_channelCount; i++ ) {     // hold only the newest Samples
      if( static_cast<unsigned int>(dataBuffer.at(i).size()) > maxElementCount ) {
        dataBuffer.at(i).erase( dataBuffer.at(i).begin(), dataBuffer.at(i).end()-maxElementCount );
      }
    }
  }

}
Diese Prozedur wird aus einem anderen Thread heraus aufgerufen (QT)...

Eventuell kommen meine ganzen Probleme auch aus dem (fiesen) Treiber der Messkarte:
Das Dingen wurde von der Firma innovative-dsp bei Jungo eingekauft und ist so ein super-ach-so-tolles Teil, bei dem man in Visual Basic die einzelnen Funktionosaufrufe des Kernels ausprogrammiert und dann das Dingen für Windows/Linux/Mac in einem Abwasch kompilieren kann...
... kann doch nicht ernsthaft funktionieren.
Aber an dieser Kernelsache bin ich bereits dran. Die Jungs von innovative-dsp habe ich schon angespitzt...

Nun habe ich eben den obigen code in das Programm hinzugefügt und nichts funktioniert mehr.

*grübel*

Danke,
Lev

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: vector< vector<int>* >

Beitrag von Xin » Mo Aug 27, 2012 4:42 pm

Hey, Lev,

lange nix mehr gehört. Lebst ja noch. ^^
Leverator hat geschrieben:bei mir schmiert ein Programm mit einem Segmentationfault ab - was manchmal nicht weiter ungewöhnlich ist
Wer sieht den ausschlaggebenden Hinweis? ;->
Leverator hat geschrieben:Wer sieht meinen Fehler?
Lass mich raten, die Funktion, die setChannelCount() ruft, sieht ungefähr so aus:

Code: Alles auswählen

DSV * dsvPointer = NULL;

dsvPointer->SetChannelCount( x );
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Leverator
Beiträge: 37
Registriert: Mo Jan 30, 2012 9:28 pm
Wohnort: ::1

Re: vector< vector<int>* >

Beitrag von Leverator » Mo Aug 27, 2012 9:10 pm

Moin Xin,

ich kanns zwar jetzt nicht mehr beweisen, aber auf die Lösung des Problems bin ich in der Zwischenzeit selber gekommen... ;)
Also: Du hast Recht. Es war wirklich ein uninitialisierter Pointer auf das dsv-Objekt...


Grüße,
Lev

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: vector< vector<int>* >

Beitrag von Xin » Mo Aug 27, 2012 9:36 pm

Leverator hat geschrieben:ich kanns zwar jetzt nicht mehr beweisen, aber auf die Lösung des Problems bin ich in der Zwischenzeit selber gekommen... ;)
Ich will's Dir mal so glauben. :-)
Leverator hat geschrieben:Also: Du hast Recht. Es war wirklich ein uninitialisierter Pointer auf das dsv-Objekt...
Hier ist Dein Hinweis:

Code: Alles auswählen

ddd meldet beim Versuch dataBuffer zu zeigen, daß er nicht auf die Adresse 0x18 zugreifen könne...
this ist also 0; vor dataBuffer sind 24 Bytes Daten anderer Membervariablen. Wenn Du Adressen hast, die sehr klein sind, kann man davon ausgehen, dass man über einen Nullpointer zugreift.

Was mich nur wundert ist, dass Du Member mit Underline hast (_channelCount) und welche ohne (dataBuffer). Da wusste ich nicht wirklich was mit anzufangen.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Antworten