[C++] Array verliert Werte

OP Persönliche Seite #3438167
Lesenswert?

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
}
#3438173
Lesenswert?

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 #3438210
Lesenswert?

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,
OP Persönliche Seite #3438214
Lesenswert?

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.
#3438223
Lesenswert?

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.
#3438341
Lesenswert?

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.
Gast #3438866
Lesenswert?

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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren