[C++] Array verliert Werte

OP Persönliche Seite #3438167
Ich habe ein Array von void-Zeigern, genannt quantities. Ein Zeiger aus 
diesem Array zeigt auf ein int-Array. Dieses wird in der Methode void 
readConfigFile(string configFile) möchte ich mit der Mehtode int 
get(quantity::ofTypeInt q, size_t index); die Werte aus diesem int-Array 
auslesen.

Wenn ich das erste Element im int-Array mit
1
((int*)quantities[L])[0] = 7;
belege und es gleich in der nächsten Zeile auslese, funktioniert es ohne 
Probleme. Greife ich aber auf diesen Zeiger später außerhalb der Methode 
void readConfigFile(string configFile) zu (z.B. per get(L, 0)), bekomme 
ich keine 7 sondern irgend einen Müll. Woran kann das liegen?


inout.h
1
#ifndef INOUT_H
2
#define INOUT_H
3
#include "common.h"
4
#include <iterator>
5

6
using std::cout;
7
using std::cin;
8
using std::endl;
9
using std::flush;
10
using std::string;
11
using std::ifstream;
12
using std::ofstream;
13
using std::istringstream;
14
using std::istream_iterator;
15

16
namespace quantity {
17
  enum ofTypeInt {
18
    L,
19
    T,
20
    NLSteps,
21
    NTSteps,
22
    deltaStep,
23
    ofTypeIntCount = 5
24
  };
25
  
26
  enum ofTypeFp {
27
    dt,
28
    tEql,
29
    tAvg,
30
    ofTypeFpCount = 3
31
  };
32
  
33
  enum common {
34
    length = -1
35
  };
36
}
37

38
class InputOutput {
39
public:
40
  InputOutput();
41
  ~InputOutput();
42

43
  int get(quantity::ofTypeInt q);
44
  int get(quantity::ofTypeInt q, size_t index);
45
  fp_type get(quantity::ofTypeFp q);
46
  fp_type get(quantity::ofTypeFp q, size_t index);
47
  
48
   void readConfigFile(string configFile);
49
  
50
private:
51
  void *quantities[quantity::ofTypeIntCount + quantity::ofTypeFpCount];
52
};
53

54
#endif // INOUT_H


inout.cpp
1
#include "inout.h"
2
#include <boost/lexical_cast.hpp>
3

4
using std::vector;
5
using std::back_inserter;
6

7
using namespace quantity;
8

9
InputOutput::InputOutput() {
10
}
11

12
InputOutput::~InputOutput() {
13

14
}
15

16
void InputOutput::readConfigFile(string configFile) {
17
  string tmpStr;
18
  ifstream inputStream;
19
  
20
  if(configFile != "") {
21
    cout << "Loading configuration file " << configFile << endl;
22
    inputStream.open(configFile.c_str());
23
    do {
24
      getline(inputStream, tmpStr);
25
      cout << "line: " << tmpStr << endl;
26
      istringstream inputStringStream(tmpStr);
27
      vector<string> tokens;
28
      copy(istream_iterator<string>(inputStringStream), istream_iterator<string>(), back_inserter<vector<string>>(tokens));
29
      if(tokens.size() > 0) {
30
        if(tokens.at(0) == "L:") {
31
          quantities[NLSteps] = new int;
32
          *(int*)quantities[NLSteps] = tokens.size() - 1;
33
          
34
          quantities[L] = new int[*(int*)quantities[NLSteps]];
35
          
36
          ((int*)quantities[L])[0] = 7;
37
          cout << "test " <<  ((int*)quantities[L])[0] << endl;
38
      }
39
    } while(tmpStr != "");
40
    inputStream.close();
41
  }
42
  
43
}
44

45

46

47
int InputOutput::get(quantity::ofTypeInt q, size_t index) {
48
  switch(q) {
49
    case L: return ((int*)quantities[L])[index]; break;
50
    default: return 0;
51
  }
52
}
Maxim S. schrieb:
> Greife ich aber auf diesen Zeiger später außerhalb der Methode
> void readConfigFile(string configFile) zu (z.B. per get(L, 0)), bekomme
> ich keine 7 sondern irgend einen Müll. Woran kann das liegen?

Sind denn die Variablen auf die die Zeiger zeigen ausserhalb der Methode 
überhaupt noch gültig? Oder waren das in der Methode lokal angelegte 
Variablen?

>Array verliert Werte
Köstlicher Titel :-) Dann musst du es abdichten.
Gast
Hallo,

zur Lösung kann ich nur ein beitragen.

Schmeiß dein void array weg. Das ist C und du willst so was nicht in C++ 
machen. (Da es unhöflich ist zu schreien, stell dir einfach alles in 
Großbuchstaben vor :)

Mit Void Zeigern arbeitet man in C++ nicht. in C++ will und kann man 
streng typisiert arbeiten. Das versuchst du zu umgehen.

Wenn du noch nicht weißt, was du in deinem Array speichern willst, 
benutz Templates oder in deinem Fall gleich einen std::vector

Grüße,
nicht "Gast" schrieb:

> Wenn du noch nicht weißt, was du in deinem Array speichern willst,
> benutz Templates oder in deinem Fall gleich einen std::vector

Zumal in diesem Beispiel wirklich nicht ersichtlich ist, wozu dieses 
void* Array tatsächlich gut sein soll, ausser das man sich durch 
ständige Casts selber ins Knie schiesst.
Maxim S. schrieb:
> Udo Schmitt schrieb:
>> Sind denn die Variablen auf die die Zeiger zeigen ausserhalb der Methode
>> überhaupt noch gültig? Oder waren das in der Methode lokal angelegte
>> Variablen?
>
> void *quantities[N] ist im Header deklariert. Das int-Array wird in
> readConfigFile() mit new definiert, muss also nach meinem Wissen auch
> außerhalb der Methode verfügbar sein.

Im Prinzip ja.
Solange du nur ein einziges derartiges InputOutput  Objekt hast.

Wir sind wieder dort, wo wir schon so oft waren: Mit den gegegenen 
INformationen kann man nicht entscheiden wo das konkret vorleigende 
Problem tatsächlich liegt. Man kann allerdings, abseits vom konkreten 
Problem schon sagen, dass der ganze Aufbau der Klasse zumindest 
zwielichtig ist. Das löst zwar das Problem nicht und eröffnet eine 
weitere Baustelle. Allerdings eine, die man auch fixen sollte - selbst 
wenn sie mit dem momentanen Problem erst mal wahrscheinlich nichts zu 
tun hat.
Maxim S. schrieb:
> Ok, das war Quatsch. Ich bin auf Templates umgestiegen. Trotzdem würde
> mich die Fehlerquelle interessieren

bau Testcode ein.

Ausgaben in:
* Konstruktor
* Destruktor

In der Abfrage-Funktion testen auf 0-Pointer

Copy Constructor und Assignment Operator durch setzen in die 
private-Sektion der Klasse und nicht implementieren unbrauchbar machen. 
Das sollte man generell immer machen, wenn man sich selber an 
dynamischer Resource-Verwaltung versucht und noch nicht weiß wie man die 
beiden implementieren soll bzw. die nicht implementieren will. Ein 
Referenz-& in einer Funktions-Argument Liste ist schnell vergessen und 
dann wird eine Kopie der Pointer mit katastophalen Konsequenzen gemacht.
Ich seh nicht, inwiefern da jetzt Templates einen Vorteil gegenüber
einem simplen
1
...
2

3
  private:
4
    std::vector<int> L_Steps;
5
    std::vector<int> N_Steps;
6
    int              Delta_Step;
7

8
    double dt;
9
    double tEql;
10
    double tAvg;
11
};
bringt.
Gast
Hier

          quantities[NLSteps] = new int;
          *(int*)quantities[NLSteps] = tokens.size() - 1;

          quantities[L] = new int[*(int*)quantities[NLSteps]];

wird doch ein Element zu wenig angelegt, oder?
(Also bei tokens.size()==1 gibt das new int[0]).

Der Code ist schrecklich. Ich wuerde auch empfehlen in umzuschreiben,
oder eine Menge Kommentare dazu zu machen.

Gruss

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 12 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.