[c++] Implementation von strcpy()/ strcat() / Zuweisung an mit new erzeugtes Objekt

radazong

Mitglied
Hallo :)

Habe mal eine Frage. Undzwar tritt in meinem Programm ein Fehler auf, den ich einfach nicht nachvollziehen kann. Vielleicht kann mir das ja jemand erklären:

Ich versuche gerade eigene Implementationen von strcpy(), strcat() usw... zu machen (Programmieraufgabe aus einem Buch). Strcpy() funktioniert auch einwandtfrei:
Code:
void strcpy(char*goal, const char* source)
{
     while(*goal++=*source++);
}
Nur, wenn ich jetzt versuche äquivalenten Code in meiner strcat()-Funktion zu nutzen:

Code:
char* cat(const char* target,const char* source)
{
      char* temp=new char[test::strlen(target)+1];
      
      while(*temp++=*target++);         //...<-- Diesen Part hier
      /*--*temp=*source;
      while(*temp++=*source++);
      */
      return temp;
}

Enthält mein char* nach Zuweisung dieser Funktion nur ein einzelnes Zeichen (im moment ein Tilde~ - aber das ist wohl mehr Zufall denke ich^^):

Code:
char* Ziel=test::cat(Test,Test2);   //Test ist ein gültiger C-String

Wenn ich nun jedoch den Code in der strcat-Funktion durch einen Aufruf von test::strcpy() ersetze, funktioniert alles ohne Probleme. Wie kann sowas angehen?

Bin für jede Hilfe dankbar,

Gruß
 
Hi.
Nur, wenn ich jetzt versuche äquivalenten Code in meiner strcat()-Funktion zu nutzen:

Code:
char* cat(const char* target,const char* source)
{
      char* temp=new char[test::strlen(target)+1];
      
      while(*temp++=*target++);         //...<-- Diesen Part hier
      /*--*temp=*source;
      while(*temp++=*source++);
      */
      return temp;
}
Da gibt es mehrere Probleme in deinem Code. Erstens, wenn du die Strings konkatenieren willst, musst du auch soviel Speicher reservieren, das beide Strings in den Speicher passen, d.h. strlen(target) + strlen(source) + 1.

Warum benutzt du überhaupt diese temp Variable? Das Ergebnis bzw. das Ziel der Konkatenierungsoperation ist doch "target"! Du müßtest doch lediglich das Ende des Strings "target" suchen und ab da den String "source" anhängen. (Dann darf der erste Parameter natürlich nicht vom Typ "const char*" sein.)
Enthält mein char* nach Zuweisung dieser Funktion nur ein einzelnes Zeichen (im moment ein Tilde~ - aber das ist wohl mehr Zufall denke ich^^):

Code:
char* Ziel=test::cat(Test,Test2);   //Test ist ein gültiger C-String
Was ist der Inhalt von Test und Test2 - d.h. wie hast du diese Variablen initialisiert?

Gruß
 
Hallo!
Kam das ganze WE nicht an den PC. Darum jetzt erst die Antwort.
zu 1.) Ich hatte genug Speicher reserviert (genau wie du beschrieben hast), habe den Code bloß zum testen des strcpy()-Codes umgeschrieben - aber danke.

zu 2.) Ich nutze diese temp-Varialble, um die Adresse für den mit "new" erzeugten Speicher zu erhalten. In der Aufgabe, die ich gerade zu lösen versuche, sollte ich den entsprechenden Speicher mit "new" reservieren, und ich wusste nicht, wie ich die Adresse sonst erhalten soll.

und zu 3.) Test und Test2 sind const char* . Habe ihnen C-Strings in Form von
Code:
char* Test"Hallo, das ist ein Test";
zugewiesen.

Und wie bereits geschrieben, funktioniert der selbe Code(nur gekapselt in einer Funktion) einwandfrei, nur wenn ich den Code direkt schreibe, geht garnichts mehr.

Gruß,
 
Hi.

Das Resultat deiner Funktion ist ein Zeiger, der ein Zeichen hinter das Terminierungszeichen zeigt da du die Variable temp in der Funktion ja veränderst. Du müßtest allerdings die Anfangsadresse des Strings zurückgeben den du von new bekommen hast (allein schon weil du den Speicher sonst gar nicht mehr freigeben kannst).

Gruß
 
Hmmm.
Habe die Funktion einfach nochmal komplett neu geschrieben, ohne mit "new" zu arbeiten. Dabei musste ich feststellen, dass meine strcpy()-Funktion nun auch nicht mehr mit einem char*-Zeiger arbeitet, sondern nur noch mit einem zuvor definiertem Array.

Kann mir vielleicht einer sagen, wie das mit der Speicherverwaltung abläuft? Denn bei meinen letzten Testläufen musste ich kein Array definieren, sondern konnte die Funktion mit char* benutzen - Zufall?

Habe mich da schon gewundert, dass die Funktion ohne feste Zielgröße arbeitet, und habe mir von einem Bekannten erklären lassen, dass mein C-String zunächst im Arbeitsspeicher, und dann auf der Festplatte an einer entsprechend großen Stelle abgelegt wird.
(Der hat das wohl irgendwie unter Linux nachvollzogen?)
 
Hmmm.
Habe die Funktion einfach nochmal komplett neu geschrieben, ohne mit "new" zu arbeiten. Dabei musste ich feststellen, dass meine strcpy()-Funktion nun auch nicht mehr mit einem char*-Zeiger arbeitet, sondern nur noch mit einem zuvor definiertem Array.
Der Speicher für das Target (und selbstverständlich auch das Ziel) muss vor dem Funktionsaufruf alloziert worden sein. Das Target muss außerdem auf einen beschreibbaren Speicherbereich verweisen - das ist bei einem konstanten Array nicht der Fall:
C:
const char[] t1 = "hallo";
const char* t2 = "xyz";

strcpy(t1, "abc"); // falsch
strcpy(t2, "abc"); // falsch

char* t3 = malloc(30);

strcpy(t3, "abc"); // ok.
Kann mir vielleicht einer sagen, wie das mit der Speicherverwaltung abläuft? Denn bei meinen letzten Testläufen musste ich kein Array definieren, sondern konnte die Funktion mit char* benutzen - Zufall?
Zeig deinen Code, damit man weiß wovon du sprichst.
Habe mich da schon gewundert, dass die Funktion ohne feste Zielgröße arbeitet, und habe mir von einem Bekannten erklären lassen, dass mein C-String zunächst im Arbeitsspeicher, und dann auf der Festplatte an einer entsprechend großen Stelle abgelegt wird.
(Der hat das wohl irgendwie unter Linux nachvollzogen?)
Da hast du entweder etwas falsch verstanden, oder dein Bekannter hat Unsinn erzählt.

Gruß
 
Nunja, es gibt keinen konkreten Code...aber ich meine es in etwa so:
C:
void strcpy(char*, const char*);
//....


int main()
{
char* Test;     //Funktionierte bei meinen letzten Testläufen auch ohne malloc()
char* Test2="Hallo, das ist ein test";

//...

strcpy(Test,Test2);

}


Jetzt auf einmal geht das nicht mehr, und ich muss zunächst ein Array(oder eben malloc()) erstellen.

C:
//...

char Test[255];

//... Arbeiten mit Test

Naja, habe es nun soweit erstmal ohne "new" gemacht, und es geht. So ganz klar ist mir das alles noch nicht, aber es ist ja schließlich auch der Sinn von Übungsaufgaben, durch praktische Erfahrungen dazuzulernen.
 
Hi.

Das es mal ohne Speicherreservierung funktioniert hat, war reiner Zufall. Du hast dann dadurch irgendwas überschrieben und hattest Glück des es nichts wichtiges war und du keinen Speicherzugriffsfehler bekommen hast.

Gruß
 
Zurück