Zum Inhalt springen

Konvertierung Char*,CString Speicherverwaltung


schorschi

Empfohlene Beiträge

Hallo zusammen,

Ich stoße leider immer wieder auf die gleichen Problematiken. Mir fehlen einfach fundierte Kenntnisse in der Stringbearbeitung und Speicherbelegung.

SYS:W2K VC 6.0

Konkret habe ich zwei/drei Probleme.

1.a) Wenn ich meine Funktion aufrufe, wird manchmal einer der übergebene Wert nicht übernomen. Das passiert immer an der gleichen Stelle. Rufe ich die Funktion an einer andern Stelle auf, funktioniert alles reibungslos.

Beispiel:

void GibMirBlaBla(char* wert1,char*wert2,char* &wert3, char* &wert4)

{

...

}

wert1 ist dann auf einmal NULL, die andern alle korrekt. Im Debugger steht, wenn ich in die Funktion eintrette, noch der Wert korrekt drin, sobald der Pfeil vom Debugger über die erste geschweifte Klammer der Funktion geht, ist der Wert NULL.

1.b)Irgendwo in meinem Quellcode werden nacheinander 6 unterschiedliche Methoden aufgerufen welche mir char* als Ergebnis liefern. Ca 20 Zeilen später, wird das gleiche noch einmal gemacht. Beim zweiten Mal funktioniert alles so wie es soll, aber beim ersten mal wird z.B. das Ergebnis der ersten Methode durch das Ergebnis der fünten Methode überschrieben oder besser ich finde im Ergebnis der ersten Methode Teile des Ergebnisses von Methode Nr.5

Ich vermute hier das Speicher doppelt belegt wird bei Problem 1a und 1b, Sie werden wahrscheinlich die gleiche Ursache haben.

2.)Laut Netz soll man char* ganz einfach in CString konvertieren.Supi denkste, wenn ich einen bestimmten char*=CString setze oder mit CString.Insert lade, bekomme ich am Ende des Strings zwei bis drei Sonderzeichen angehängt die dort nicht sein dürfen. Nach zwei Stunden genervten probieren und suche im Netz bin ich hingegangen und habe den char* Zeichenweise in den CString kopiert. Aber das kanns doch nicht sein.

Kenntnisse über Fehlerbehandlung habe ich insoweit das ich mit dem Debugger schrittweise den Code abklappere und Variablen auslesen kann....und das war es.

Ich weiß ich habe sehr abstrakt geschrieben und Source ist hier nicht besonders sinnvoll wie ich meine.

Kann mir jemand eine Quelle nennen mit super einfachen Anleitungen über diese Themen : Speicherbelegung, Zeiger.

Jetzt kommt bestimmt wieder mußt Du googeln, das Problem ist eine gescheite Anleitung mit allen Fallstricken und meine wohl falschen Suchbegriffe.

Danke

Joerg

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ja habe ich, denke ich zumindest.

bei char* terminiere ich mit strcat(Name,"\0");

bei char[] mit Name[wert]='\0'

obwohl ich mir hier nicht sicher bin, wenn ich zum Beispiel mitten rein terminiere zeigt es offensichtlich keine wirkung, deshalb wandel ich meist in Pointer um und terminiere Sie dann.

Mittlerweile habe ich meine eigenen Funktionen durchgesehen, diejenigen wo ich Probleme habe, sind alle nach meiner Meinung vom Speicher her sauber deklariert. Wenn ich überhaupt einen Pointer benutze dann reservierung mit malloc und anschließend mit free wieder freigegeben. Die lokalen Variablen haben ja eh nur eine gültigkeitsdauer bis zum ende der Funktion, soweit ich weiß.

Die Pointer welche ich übergebe sind auch meist eine Zeile davor deklariert und initialisiert worden, vor dem Funktionsaufruf.

Link zu diesem Kommentar
Auf anderen Seiten teilen

bei char* terminiere ich mit strcat(Name,"\0");
Das bringt überhaupt nichts. Strcat sucht nach einer Nullterminierung, um herauszufinden, wo es anfügen muss.

Dieser Code fügt also nur dort eine Nullterminierung ist, wo schon eine ist, ansonsten schreibt es dir irgendwo dahinter im Speicher herum.

Irgendwo in meinem Quellcode werden nacheinander 6 unterschiedliche Methoden aufgerufen welche mir char* als Ergebnis liefern.
Und wie halten es diese Methoden mit der Speicherverwaltung? Zeiger zurückzugeben ist nicht trivial.
Link zu diesem Kommentar
Auf anderen Seiten teilen

Was meinst du mit trivial ? Das Vorsicht geboten ist, weiß ich. Aber weiß noch nicht genau worauf ich achten soll. Ich denke immer Speicher reservieren, nutzen und freigeben ist die wichtigste Regel.

Was würdest du vorschlagen zum terminieren ? Mit strlen() auf das letzte Zeichen, und wie kopiere ich in einem char* dann das "\0". Mit Name="\0" klapps ja nicht.

Das sind die fehlenden Kenntnisse von dennen ich sprach, da muß ich noch mal ran...

Link zu diesem Kommentar
Auf anderen Seiten teilen

Was meinst du mit trivial ? Das Vorsicht geboten ist, weiß ich. Aber weiß noch nicht genau worauf ich achten soll. Ich denke immer Speicher reservieren, nutzen und freigeben ist die wichtigste Regel.
Was machen diese Methoden denn? Geben sie einen Zeiger auf dynamisch angeforderten Speicher zurück? Oder statischen? Oder gar lokalen?

Was würdest du vorschlagen zum terminieren ? Mit strlen() auf das letzte Zeichen
Mit strlen hast du dasselbe Problem wie mit strcat. Strlen sucht nach der Nullterminierung, um die Länge zu bestimmen, funktioniert also nicht mit Strings, die gar nicht nullterminiert sind.

Wenn deine Stringdaten tatsächlich nicht nullterminiert sein sollten, musst DU wissen, wie lang die Daten sind. Du kannst das nicht nachträglich ermitteln. Wo kommen diese Daten denn her?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Was machen diese Methoden denn? Geben sie einen Zeiger auf dynamisch angeforderten Speicher zurück? Oder statischen? Oder gar lokalen?

Es exitiert ein (normalerweise) terminerter Pointer. Den übergebe ich als Value an eine Funktion. Als Vergleichswerte zum suchen für die Funktion diehnen ebenfalls zwei Nullterminierte Pointer.Zusätzlich übergebe ich zwei Referenzen für den gefundenen Wert & den Stringrest, und da weiß ich nicht, ob ich es richtig mache, diese bilde ich mit char* pointer=NULL und übergebe sie.

In der Funktion vergleiche ich die Pointer mit pointer[counter]==pointer[pointer], bei Erfolg kopiere ich den Pointer[counter] in einen normalen char[]. Am Ende des Vergleiches kopiere ich den erstellten char[] in die übergebenen Referenzen. Ziehmlich umständlich, denke ich.

Beispiel:

void myFunktion::GetPartOfString(char *String, char *FirstVglstr, char *LastVglstr, char *&Find, char *&Rest)

{

int size = strlen(String);

int sizeVgl = strlen(FirstVglstr);

int sizeVglEnde = strlen(LastVglstr);

int counter = 0;

int copy = 0;

unsigned int status = 0;

int counterVglStart = 0;

int counterVglEnde = 0;

int tmpcounter = 0;

char tmp[8192];

char tmp2[8192];

...

}

Ich denke mal das ich hier keinen Speicher freigeben muß, oder besser kann.

Mit strlen hast du dasselbe Problem wie mit strcat. Strlen sucht nach der Nullterminierung, um die Länge zu bestimmen, funktioniert also nicht mit Strings, die gar nicht nullterminiert sind.

Leuchtet ein, wenn du es sagst.

Wenn deine Stringdaten tatsächlich nicht nullterminiert sein sollten, musst DU wissen, wie lang die Daten sind. Du kannst das nicht nachträglich ermitteln. Wo kommen diese Daten denn her?

Unterschiedlich. Hauptsächlich unbekannte Textdateien welche nach verschiedenen Mustern durchsucht werden. Ich habs auch schon mit strstr() und strtok() versucht, mußte aber Feststellen, dass sobald ich ein anderes Muster angebe es nicht mehr funktioniert. Meine erstellten Funktionen Funktionieren aufgrund des Umständlichen aber auch detailirten Aufbaus einwandfrei.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Am Ende des Vergleiches kopiere ich den erstellten char[] in die übergebenen Referenzen. Ziehmlich umständlich, denke ich.
Wie kopierst du denn? Mit strcpy?

In einen Zeiger, den du als Referenz übergeben hast, und der mit "\0" initialisiert wurde? Ohne neuen Speicher anzufordern?

Das kann nur in die Hose gehen. Dein Zeiger zeigt auf das Stringliteral "\0", da darfst du gar nichts reinkopieren.

Übrigens: "\0" ist sowieso Quatsch. Stringliterale sind automatisch nullterminiert. Das Literal "" besteht aus einem Stringendezeichen, das Literal "\0" also aus zweien.

Ich würde dir dringend empfehlen, das ganze auf eine Stringklasse, z.B. std::string umzustellen, die dir die Speicherverwaltung abnimmt.

Link zu diesem Kommentar
Auf anderen Seiten teilen

Wie kopierst du denn? Mit strcpy?

In einen Zeiger, den du als Referenz übergeben hast, und der mit "\0" initialisiert wurde? Ohne neuen Speicher anzufordern?

Das kann nur in die Hose gehen. Dein Zeiger zeigt auf das Stringliteral "\0", da darfst du gar nichts reinkopieren.

Nein, in der Funktion bestimme ich die größe des zusammengesetzten char[] und reserviere Speicher für den mit NULL übergebenen Pointer. Hintergrund war das wenn ich das Ergebnis nicht mehr brauche kann ich es dort wieder freigeben.Ich fand es nicht gut in der Funktion einen Pointer zu bilden Speicher zu reservieren und ihn zurückzugeben, ich wüßte nicht, wie ich speicherplatz wieder freigeben soll hinter einem return, da komme ich ja nie hin.

Übrigens: "\0" ist sowieso Quatsch. Stringliterale sind automatisch nullterminiert. Das Literal "" besteht aus einem Stringendezeichen, das Literal "\0" also aus zweien.

das dachte ich mir schon...

Ich würde dir dringend empfehlen, das ganze auf eine Stringklasse, z.B. std::string umzustellen, die dir die Speicherverwaltung abnimmt.

Es heißt doch immer möglichst nache am ANSI zu bleiben, naja ich wollte zumindest mit der Stringbearbeitung dort bleiben.Mit CString klappt es natürlich auch. Aber Tatsache ist ja das ich an der Basis Fehler mache und ich weiß nicht wo. Zur Zeit habe ich wieder eine Fehlermeldung welche mich auf schlechte Speicherverwaltung hinweißt.Ich habe eine eine Variable eines RecordSet. Klappte alles wunderbar, bis jetzt. Irgendwo habe ich da 'nen crash und ich kenne mich nicht mit den tools zur überrüfung des Speichers oder/Stack aus.Habe ich noch nie gemacht...

Sag mal Klotzkopf, kann ich dir 'ne private Nachricht schicken ?

Link zu diesem Kommentar
Auf anderen Seiten teilen

Es heißt doch immer möglichst nache am ANSI zu bleiben, naja ich wollte zumindest mit der Stringbearbeitung dort bleiben.
std::string ist (wie alles, was im Namespace std liegt) Bestandteil des C++-Standards. Wo ist das Problem?

Sag mal Klotzkopf, kann ich dir 'ne private Nachricht schicken ?
Ob du das kannst, weiß ich nicht. Falls du wissen wolltest, ob du das darfst: Ja, wenn du meinen Nick richtig schreibst ;)
Link zu diesem Kommentar
Auf anderen Seiten teilen

std::string ist (wie alles, was im Namespace std liegt) Bestandteil des C++-Standards. Wo ist das Problem?

Ob du das kannst, weiß ich nicht. Falls du wissen wolltest, ob du das darfst: Ja, wenn du meinen Nick richtig schreibst ;)

Sorry, das mit dem Namen ist mir natürlich erst jetzt aufgefallen:rolleyes:

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...