2016-10-12 3 views
0

Ich arbeite derzeit an einer Klasse, die Strings speichert. Es soll zwei separate Konstruktoren haben, von denen einer dem Benutzer erlaubt, das Objekt mit Argv-Argumenten zu initialisieren, während der andere das Objekt mit Umgebungstypen von Argumenten initialisiert.Speichern von Umgebungsvariablen in einem dynamisch zugewiesenen Array

Alles funktioniert perfekt, wenn ich Argv verwende, das Objekt ist korrekt initialisiert und speichert jede Zeichenfolge, die ich in der Befehlszeile hinzugefügt. Allerdings stoße ich für die Umgebungsvariablen in Schwierigkeiten. Das Speichern jeder Umgebungszeichenkette in meinem Objekt scheint zu ambitioniert, da es den Speicher übersteigt, auf den ich Zugriff habe.

Gibt es Möglichkeiten, die Größe der Umgebungsvariablen zu reduzieren oder die Anzahl der Variablen zu steuern, die main als Argument benötigt?

Fyi, die Klasse enthält zwei Datenelemente: eins speichert die Menge der gespeicherten Strings, während das andere das eigentliche Array von Strings ist. Ich habe versucht, ein dynamisch zugewiesenes Array zu verwenden, wobei die Menge der Umgebungsvariablen als Argument verwendet wurde (gezählt mit einer for-Schleife). Es scheint jedoch zu viele Variablen zu geben, daher habe ich einen bad_alloc Fehler.

Stringstore::Stringstore(char ** envp) 
{ 
    for (char** env = envp; *envp != nullptr; ++env) 
     ++d_size; 
    d_str = new string[d_size]; 
    for (int index=0; index != d_size; ++index) 
     d_str[index] = envp[index]; 
} 

class Stringstore 
{ 
string *d_str; 
int d_size; 
public: 
    Stringstore(int argc, char **argv1); 
    Stringstore(char **envp); 
}; 


int main(int argc, char **argv, char **envp) 
{ 
    Stringstore(envp);  
} 
+0

vielleicht könnten Sie schreiben einige [MCVE]? Auf einem modernen Computer bin ich überrascht, dass du ein env nicht kopieren kannst. Variablen. –

+0

Ich habe den Kerncode hinzugefügt, den ich derzeit habe, um ein Objekt mit Umgebungsvariablen zu initialisieren. – Blackjaguar

+0

Was sind die Symptome des Fehlers, wäre es zufällig eine Endlosschleife? (Und angenommen, ein Speicherfehler wäre falsch) –

Antwort

1

Diese Schleife, die Sie verwenden, um zu zählen, wie viele env. Vars, die Sie erhalten, ist eine Endlosschleife. envp ändert sich nicht von einer Iteration zur nächsten.

for (char** env = envp; *envp != nullptr; ++env) 
     ++d_size; 

Da envp nicht nullptr am Start, die Sie nie den Ausgang Zustand erreichen, die Sie macht glauben, dass Sie Speicher laufen lassen, aber nicht: Sie aus CPU laufen :)

Another Fehler: in der Haupt sollten Sie ein Objekt bauen nicht versuchen, „cast“ zu Stringstore:

int main(int argc, char **argv, char **envp) 
{ 
    Stringstore the_string_store(envp);  
} 

Beachten Sie, dass ein Vektor (auto-realloc, keine new, trivial Kopie-Konstruktor für die Klasse) mit vielleicht hätte ein V Dieser Fehler wurde behoben. Lassen Sie mir einen festen Code schlagen (was die env am Ende druckt zu beweisen, dass es funktioniert)

#include <string> 
#include <vector> 
#include <iostream> 

using namespace std; 

class Stringstore 
{ 
std::vector<string> d_str; 
public: 
    Stringstore(int argc, char **argv1); 
    Stringstore(char **envp); 
}; 
Stringstore::Stringstore(char ** envp) 
{ 
    // store each env. string 
    for (; *envp != nullptr; ++envp) 
     d_str.push_back(*envp); 

    // debug: print the contents of the vector 
    for (auto it : d_str) 
    { 
     cout << it << endl; 
    } 
} 


int main(int argc, char **argv, char **envp) 
{ 
    Stringstore s(envp);  
} 

den Lauf mir diese:

ALLUSERSPROFILE=C:\ProgramData 
APPDATA=D:\Users\xxxxxxx\AppData\Roaming 
CommonProgramFiles=C:\Program Files (x86)\Common Files 
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files 
CommonProgramW6432=C:\Program Files\Common Files 
COMPUTERNAME=xxxxxx 
... 

Die letzte Mal bearbeitet: wenn Sie nicht erlaubt sind zu verwenden, vector, auch das ist ein doofer, aber diese feste Version der Methode funktioniert:

Stringstore::Stringstore(char ** envp) 
{ 
    // make a copy so we can count and preserve the original pointer 
    // for the second pass: the string copy 
    char **envp_copy = envp; 
    d_size = 0; // you forgot to initialize it too :) 

    for (; *envp_copy != nullptr; ++envp_copy) 
     d_size++; // count 

    // the rest is your code, unchanged 
    d_str = new string[d_size]; 
    for (int index=0; index != d_size; ++index) 
     d_str[index] = envp[index]; 

    // debug: print env 
    for (int index=0; index != d_size; ++index) 
    { 
     cout << d_str[index] << endl; 
    } 

} 
+0

Danke für Ihre Antwort! – Blackjaguar

+0

Vielen Dank für Ihre Antwort! Die Besetzung ist eigentlich ein Typ. Haben Sie weitere Vorschläge, um alle Strings von environ in einem Array zu speichern? – Blackjaguar

+0

Hölle ja. siehe meine letzte Bearbeitung. –

Verwandte Themen