Discussion:
newbie: kopiere char* to char*
(zu alt für eine Antwort)
t***@gmail.com
2014-04-09 19:15:45 UTC
Permalink
Raw Message
Hallo,

ich bin newbie in Sachen C. Und: ich möchte einem char* einen anderen chhar* zuweisen?
Geht das? Danke.

o-o

THomas
Matthias Fulz
2014-04-09 19:33:24 UTC
Permalink
Raw Message
Post by t***@gmail.com
Hallo,
ich bin newbie in Sachen C. Und: ich möchte einem char* einen anderen
chhar* zuweisen? Geht das? Danke.
o-o
THomas
Naja dazu gibt es mehrere Möglichkeiten:

1.) Einfach nur den pointer setzen - damit hast du keine Kopie beide char*
zeigen dann auf den selben Speicherbereich:

char *src;
char *dst;

src = dst;

Wenn du jetzt z.b. "Hallo" in dem char* hast dann würde:

src[0] = 'B';

auch dst auf "Ballo" setzen.


2.) Richtiges kopieren:

du musst dafür dann entsprechend den Speicher allozieren (Ich gehe jetzt mal
davon aus, dass du einen null-terminierten String in deinem char * hast und
deine Quelle char *src heisst):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv) {
char *src = "Hallo\0";
char *dst;
size_t srcSize = strlen(src) + 1;
dst = (char *) malloc(sizeof(char) * srcSize);
if(!dst)
exit(-1); // speicherfehler

dst = (char *) memcpy(dst, src, srcSize);
if(!dst)
exit(-1); // memcpy fehler

printf("String src: %s\n", src);
printf("String dst: %s\n", dst);

exit(0);
}

damit hast du dann den ganzen Speicherbereich mit Inhalt (+ \0-byte)
kopiert.

Es gibt natürlich noch viele andere Möglichkeiten das zu erledigen ;)

Hoffe das hat dir ein bisschen geholfen.

Gruß,

Matthias
--
"Those who cannot remember the past are condemned to repeat it"
|--< Geroge Santayana >--|
Thomas Rachel
2014-04-10 07:33:47 UTC
Permalink
Raw Message
Post by Matthias Fulz
dst = (char *) malloc(sizeof(char) * srcSize);
Warum castest Du den Rückgabewert von malloc()?

Das ist unnötig und schlechter Stil, weil damit Probleme versteckt
werden, die z. B. durch ein vergessenes #include <stdlib.h> verursacht
werden.

In C++ mag das anders aussehen (dort ist void * nicht mit allem
möglichen zuewisungskompatibel, aber dort verwendet man aj auch kein
malloc()), aber hier geht es um C.
Post by Matthias Fulz
dst = (char *) memcpy(dst, src, srcSize);
Hier erst recht.


[korrekten Rest gesnipt]


Thomas
Matthias Fulz
2014-04-10 08:07:08 UTC
Permalink
Raw Message
Post by Thomas Rachel
Post by Matthias Fulz
dst = (char *) malloc(sizeof(char) * srcSize);
Warum castest Du den Rückgabewert von malloc()?
Das ist unnötig und schlechter Stil, weil damit Probleme versteckt
werden, die z. B. durch ein vergessenes #include <stdlib.h> verursacht
werden.
In C++ mag das anders aussehen (dort ist void * nicht mit allem
möglichen zuewisungskompatibel, aber dort verwendet man aj auch kein
malloc()), aber hier geht es um C.
Post by Matthias Fulz
dst = (char *) memcpy(dst, src, srcSize);
Hier erst recht.
[korrekten Rest gesnipt]
Thomas
Guter Punkt hast du natürlich Recht. Ja ich bin momentan auf C++ getrimmt
und hatte das einfach aus reiner Gewohnheit gemacht :/
Georg Bauhaus
2014-04-10 08:53:30 UTC
Permalink
Raw Message
Post by Matthias Fulz
size_t srcSize = strlen(src) + 1;
Hier kann man noch betonen, dass strlen mit Umsicht
genutzt werden sollte, besonders wenn auf unbekannte
Daten zugegriffen wird: Wenn nicht bekannt ist, ob
src tatsächlich NUL-teminiert ist, oder allg. bei Daten
von "außerhalb", dann sind die "n"-Varianten der gezeigten
Funktionen wahrscheinlich vorteilhaft, also z.B. strnlen.
Rainer Weikusat
2014-04-10 17:36:23 UTC
Permalink
Raw Message
Post by Georg Bauhaus
Post by Matthias Fulz
size_t srcSize = strlen(src) + 1;
Hier kann man noch betonen, dass strlen mit Umsicht
genutzt werden sollte, besonders wenn auf unbekannte
Daten zugegriffen wird: Wenn nicht bekannt ist, ob
src tatsächlich NUL-teminiert ist,
oder falls 'die Daten' ein Laengenfeld enthalten, aber von einer nicht
vertrauenswuerdigen Quelle stammen' --- und das ist jede, die nicht
Bestandteil des momentanen Programms ist: Jedes andere Programm koennte
wenigstens fehlerhaft sein und jedes unbekannte Programm, insbesondere
dann, wenn es auch noch auf einem 'unbekannten' und von jemand anderem
kontrollierten Computer lief, koennte absichtlich versuchen, Schaden
anzurichten.

Nehmen wir als vollkommen kuenstliches Beispiel mal an, das ein
Transportebenen-Verunsicherungsprotokoll eine dreiteilige
Kopfnuss-Nachricht definiert, die mit einer inhaltlich identischen
Kopfnuss-Nachricht beantwortet werden soll. Die konkrete Struktur sei

1 Byte Typfeld.
2 Byte Nusslast-Laengenfeld in umgedrehter Netztwerkreihenfolge
n Byte Nusslast, n >= 1

Der Einfachheit halber wird angenommen, dass ein
nachrichtengrenzenwahrendes Protokoll verunsichert werden soll.

In diesem Fall sollte vor jeglicher Verarbeitung folgender Algorithmus
ausgefuehrt werden:

1. Wurden wenigstens 4 Byte empfangen? Falls nein, ist die Nachricht
ungueltig und muss ignoriert werden.

2. Entspricht der Wert des Typ-Felds dem definierten Typ fuer
'Kopfnuss-Nachricht'? Falls nein, ist es keine und sie muss ignoriert
werden.

3. Ist die dekodierte Laenge identisch zur Laenge der empfangen Daten?
Falls nein, muss die Nachricht verworfen werden.

Insofern diese Schritte nicht alle so ausgefuehrt werden, langt es
vielleicht zur akademischen Rinderwahnsinns-Beruehmtheit mit einem
grossen Kreis von Fans, deren oeffentliches Verhalten staendig in der
Naehe der Strafbarkeit schwebt, insofern sie davon ausgehen koennen,
wahrscheinlich nicht zur Rechenschaft gezogen zu werden, aber NICHT zum
Implementieren von Software, die Dritte ohne Gefahr "fuer Leib und
Leben" benutzten koennen.
Georg Bauhaus
2014-04-11 08:18:38 UTC
Permalink
Raw Message
Post by Rainer Weikusat
Nehmen wir als vollkommen kuenstliches Beispiel mal an, das ein
Transportebenen-Verunsicherungsprotokoll eine dreiteilige
Kopfnuss-Nachricht definiert, die mit einer inhaltlich identischen
Kopfnuss-Nachricht beantwortet werden soll. Die konkrete Struktur sei
1 Byte Typfeld.
2 Byte Nusslast-Laengenfeld in umgedrehter Netztwerkreihenfolge
n Byte Nusslast, n >= 1
;-)
Post by Rainer Weikusat
Insofern diese Schritte nicht alle so ausgefuehrt werden, langt es
vielleicht zur akademischen Rinderwahnsinns-Beruehmtheit mit einem
grossen Kreis von Fans, deren oeffentliches Verhalten staendig in der
Naehe der Strafbarkeit schwebt, insofern sie davon ausgehen koennen,
wahrscheinlich nicht zur Rechenschaft gezogen zu werden, aber NICHT zum
Implementieren von Software, die Dritte ohne Gefahr "fuer Leib und
Leben" benutzten koennen.
Wenn ich mir General K.A.s Enterprise-Nachbau in Erinnerung rufe,
scheinen in der Szene draufgängerische Zuckungen verbreitet zu sein.
Warum dann nicht:

http://blog.fefe.de/?ts=adba343f
Rainer Weikusat
2014-04-11 11:36:24 UTC
Permalink
Raw Message
Post by Georg Bauhaus
Post by Rainer Weikusat
Nehmen wir als vollkommen kuenstliches Beispiel mal an, das ein
Transportebenen-Verunsicherungsprotokoll eine dreiteilige
Kopfnuss-Nachricht definiert, die mit einer inhaltlich identischen
Kopfnuss-Nachricht beantwortet werden soll. Die konkrete Struktur sei
1 Byte Typfeld.
2 Byte Nusslast-Laengenfeld in umgedrehter Netztwerkreihenfolge
n Byte Nusslast, n >= 1
;-)
Post by Rainer Weikusat
Insofern diese Schritte nicht alle so ausgefuehrt werden, langt es
vielleicht zur akademischen Rinderwahnsinns-Beruehmtheit mit einem
grossen Kreis von Fans, deren oeffentliches Verhalten staendig in der
Naehe der Strafbarkeit schwebt, insofern sie davon ausgehen koennen,
wahrscheinlich nicht zur Rechenschaft gezogen zu werden, aber NICHT zum
Implementieren von Software, die Dritte ohne Gefahr "fuer Leib und
Leben" benutzten koennen.
Wenn ich mir General K.A.s Enterprise-Nachbau in Erinnerung rufe,
scheinen in der Szene draufgängerische Zuckungen verbreitet zu sein.
http://blog.fefe.de/?ts=adba343f
Wenn man die dummdreiste oeffentlich Rechtfertigung (Oi! Passiert halt!
Weitermachen!) beruecksichtigt, klingt das gar nicht mal so
unwahrscheinlich: Das koennte jemand sein, der sehr sorgfaeltig gelernt,
wie man dadurch, dass man die richtigen Reizthemen auf die richtige
Weise erwaehnt, einen maximalem Laerm erzeugt, in dem jeder Ansatz einer
ernsthaften, technischen Eroerterung auf eine "fuer die Oeffentlichkeit
unentwirrbare Weise" verschwindet.

Andererseits halte ich aber auch die Erklaerung, das ein
"hoffnungsfroher junger Akademiker" da einfach seinen
zusammengeschluderten proof-of-concept-Code irgendwohin geschickt und
das dann von "Freunden, Verwandten und Bekannten" ohne naehere
Betrachtung abgenickt wurde, fuer vollkommen glaubwuerdig: Es wird
ueberall nur mit Wasser gekocht. "Schicke mir den Inhalt von 64K malloc
heap"[*] kommt mir auch ein bisschen zu unzuverlaessig fuer eine
ernsthafte Hintertuer vor und die empfangene Laenge einfach zu benutzen
("geht ja um nichts") und das dann sofort zu vergessen sieht mir eher
nach 'studentischer Unart' als 'nachrichtendienstlichen Umtrieben" aus.

[*] Ich habe das bis OPENSSL_malloc zurueckverfolgt. Da 'wir' ohnehin
nur praehistorische Debian-Versionen benutzen (oldstable) betrifft mich
das nicht direkt :-).
Stefan Reuther
2014-04-11 16:23:39 UTC
Permalink
Raw Message
Post by Rainer Weikusat
Nehmen wir als vollkommen kuenstliches Beispiel mal an, das ein
Transportebenen-Verunsicherungsprotokoll eine dreiteilige
Kopfnuss-Nachricht definiert, die mit einer inhaltlich identischen
Kopfnuss-Nachricht beantwortet werden soll. Die konkrete Struktur sei
1 Byte Typfeld.
2 Byte Nusslast-Laengenfeld in umgedrehter Netztwerkreihenfolge
n Byte Nusslast, n >= 1
Der Einfachheit halber wird angenommen, dass ein
nachrichtengrenzenwahrendes Protokoll verunsichert werden soll.
Das ist die Stelle, wo ich mich frage: wozu braucht man eigentlich dass
Nusslast-Längenfeld? Da wir ein nachrichtengrenzenwahrendes Protokoll
haben, lässt sich die Anzahl Nüsse ja aus der Nachrichtengröße abzüglich
der Anzahl Kopfnüsse berechnen.

Und da ich von Natur aus faul bin, und mir damit die Prüfung...
Post by Rainer Weikusat
3. Ist die dekodierte Laenge identisch zur Laenge der empfangen Daten?
Falls nein, muss die Nachricht verworfen werden.
...sparen kann, lass ich das Längenfeld einfach weg.

Das verbleibende Problem ist dann eher, dass ein Scherzkeks auf die Idee
kommt, mir SIZE_MAX-1 Kopfnüsse zu senden und *das* ungeprüft in malloc
reingeht...


Stefan
Rainer Weikusat
2014-04-11 17:38:10 UTC
Permalink
Raw Message
Post by Stefan Reuther
Post by Rainer Weikusat
Nehmen wir als vollkommen kuenstliches Beispiel mal an, das ein
Transportebenen-Verunsicherungsprotokoll eine dreiteilige
Kopfnuss-Nachricht definiert, die mit einer inhaltlich identischen
Kopfnuss-Nachricht beantwortet werden soll. Die konkrete Struktur sei
1 Byte Typfeld.
2 Byte Nusslast-Laengenfeld in umgedrehter Netztwerkreihenfolge
n Byte Nusslast, n >= 1
Der Einfachheit halber wird angenommen, dass ein
nachrichtengrenzenwahrendes Protokoll verunsichert werden soll.
Das ist die Stelle, wo ich mich frage: wozu braucht man eigentlich dass
Nusslast-Längenfeld? Da wir ein nachrichtengrenzenwahrendes Protokoll
haben, lässt sich die Anzahl Nüsse ja aus der Nachrichtengröße abzüglich
der Anzahl Kopfnüsse berechnen.
Im Original deswegen, weil die Nachricht vierteilig ist und wenigstens
16 Byte zufaelliges padding nach der Nutzlast enthalten soll,

https://tools.ietf.org/html/rfc6520, Abschnitt 4

Ich nehme mal an, dass auf diese Weise 'known plaintext'-Angriffe
verhindert oder wenigstens erschwert werden sollen.
Post by Stefan Reuther
Und da ich von Natur aus faul bin, und mir damit die Prüfung...
Post by Rainer Weikusat
3. Ist die dekodierte Laenge identisch zur Laenge der empfangen Daten?
Falls nein, muss die Nachricht verworfen werden.
...sparen kann, lass ich das Längenfeld einfach weg.
Selbst wenn es, wie in diesem Beispiel, auch ohne geht, wuerde ich es
auf Stimmigkeit pruefen: Wenn irgendetwas an der Nachricht 'komisch
aussieht' ist es das sicherste, sie zu verwerfen (was man im realen
Internet dann vermutlich ueber kurz oder lang aendern muesste, weil
Server von $Riesenfirma sonstwas fuer Bloedsinn in diese Feld packen und
Software von $Kleinfirma damit zurechtkommen muss ...).

Markus Schaaf
2014-04-09 19:39:53 UTC
Permalink
Raw Message
Post by t***@gmail.com
ich bin newbie in Sachen C. Und: ich möchte einem char* einen anderen chhar* zuweisen?
Du musst Code zeigen und die Umstände erklären, damit man die Frage
richtig beantworten kann. Es kann sich einfach um eine Referenz auf eine
String handeln, dann genügt eine einfache Zuweisung:

char *a, *b;
// ...
b = a;

Es kann aber auch auf "Besitz", also Speicherverwaltung ankommen. Dann
muss man wissen, welche Allokator-Funktionen benutzt werden müssen und
auf was für ein Objekt der Zeiger verweist. Wenn es sich z.B. um
Null-terminierte Strings handelt und malloc/free als Allokator benutzt
werden, kann das so aussehen:

b = strdup( a );
if( !b ) {
// nicht genug Speicherplatz
}
Rainer Weikusat
2014-04-09 20:00:25 UTC
Permalink
Raw Message
Post by t***@gmail.com
ich bin newbie in Sachen C. Und: ich möchte einem char* einen anderen chhar* zuweisen?
Geht das? Danke.
Ja. Aber dann hast Du zwei Zeiger auf ein Zeichenarray, keine zwei
Zeichenarrays.
Stefan Ram
2014-04-09 22:44:30 UTC
Permalink
Raw Message
Post by t***@gmail.com
ich möchte einem char* einen anderen chhar* zuweisen?
Geht das?
Einem Objekt des Typs »char *« kann im allgemeinen
ein Wert des Typs »char *« zugewiesen werden.
t***@gmail.com
2014-04-10 17:56:43 UTC
Permalink
Raw Message
Post by t***@gmail.com
Hallo,
ich bin newbie in Sachen C. Und: ich möchte einem char* einen anderen chhar* zuweisen?
Geht das? Danke.
o-o
THomas
Danke Männer!!! Hat alles sehr weiter geholfen! Danke.
Loading...