|
You last visited: Today at 16:20
Advertisement
Prüfen auf Gleichheit
Discussion on Prüfen auf Gleichheit within the C/C++ forum part of the Coders Den category.
06/30/2016, 16:01
|
#1
|
elite*gold: 309
Join Date: Jul 2011
Posts: 4,311
Received Thanks: 886
|
Prüfen auf Gleichheit
Kann mir jemand erklären warum zwei int's mit gleichem Wert als gleich angesehen werden aber zwei Zeichenketten mit gleichem Inhalt nicht?
Code:
int i1 = 1;
int i2 = 1;
char z1[] = "Hallo";
char z2[] = "Hallo";
if(i1 == i2) {
printf("i1 und i2 sind gleich\n"); }
if(z1 == z2) {
printf("z1 und z2 sind gleich\n"); }
else {
printf("z1 und z2 sind nicht gleich\n"); }
Ausgabe:
i1 und i2 sind gleich
z1 und z2 sind nicht gleich
|
|
|
06/30/2016, 16:08
|
#2
|
elite*gold: 0
Join Date: May 2015
Posts: 700
Received Thanks: 444
|
Zeichenketten sind Arrays, also Zeiger. Du vergleichst, ob z1 und z2 auf die selbe Speicherstelle zeigen.
Mich wundert es aber, dass die Speicherstellen in deinem Beispiel tatsächlich verschieden ist; eigentlich sollte der Compiler den selben statischen Text nur einmal im Speicher ablegen. Vermutlich ist das aber jedem Compiler frei überlassen?
Wenn der String aber nicht statisch ist, klappt das auf keinen Fall, da dann eben der selbe Text zweimal an verschiedenen Stellen im Speicher liegt. Mit strcmp() kannst du dann den Inhalt der beiden verschiedenen (und den nachfolgenden) Speicherstellen vergleichen.
Also als Beispiel, vielleicht sieht dein Speicher so aus:
Code:
z1 z2
V V
|H|a|l|l|o|\0| | |b|a|0|1|H|a|l||l|o|\0
z1 und z2 zeigen auf verschiedene Stellen (--> z1 != z2), an beiden liegt aber der selbe String.
Deine int Variablen sind hingegen keine Zeiger, also wird hier nicht die Speicherstelle sondern direkt der Inhalt verglichen. Die Variante von den Strings würde also dem entsprechen:
Code:
int a1 = 1;
int a2 = 1;
int *p1 = &a1;
int *p2 = &a2;
if (p1 == p2) { ... } else { ... }
Dann vergleichst du wieder die Speicherstellen der Zahlen.
|
|
|
06/30/2016, 16:23
|
#3
|
elite*gold: 309
Join Date: Jul 2011
Posts: 4,311
Received Thanks: 886
|
Danke für die super Erklärung! 
Ich hätte noch eine Frage:
Angenommen man erstellt ein Array mit der Größe 5: char hallo[5] = "Hallo";
Hier finden alle Zeichen gerade so Platz. Doch wo findet das '\0' Platz, wenn das Array doch mit 5 Bytes eigentlich voll ist?
|
|
|
06/30/2016, 16:43
|
#4
|
elite*gold: 0
Join Date: May 2015
Posts: 700
Received Thanks: 444
|
Das '\0' wird in dem Fall dann einfach abgeschnitten. Wenn du das Array noch kleiner machst, wird der zu große Teil auch abgeschnitten (und der Compiler gibt eine Warnung aus).
Sowas kann dann natürlich zu ungewolltem Verhalten oder Speicherzugriffsfehler führen, wenn später ein '\0' am Ende erwartet wird (fast alle str* Funktionen erwarten das). Die Funktionen würden den String dann solange weiter ablaufen, bis irgendwann zufällig ein '\0' kommt; und wenn auf Speicher dazwischen aus irgendeinem Grund nicht zugegriffen werden darf, gibt es den Speicherzugriffsfehler.
|
|
|
06/30/2016, 22:02
|
#5
|
elite*gold: 15
Join Date: Jul 2010
Posts: 3,926
Received Thanks: 1,158
|
grundsätzlich solltest du bei deinem Beispiel keine größe angeben, sprich 'char *hallo = "hallo";', da es sich um statischen text handelt kümmert der compiler sich um den Speicher. falls du aber variable größen hast, also z.b. irgend einen text einliest, so kannst und solltest du einfach einen pointer erstellen, sprich char *tmp; dort reinschreiben was du brauchst und nur wenn du das auch außerhalb der Funktion brauchst malloc aufrufen mit der passenden Größe. ein Beispiel:
Code:
void irgendwas(char *etwas){
char *buffer;
char *test = "test";
strcpy(buffer, etwas);
strcmp(buffer, test); //falls die Größe bekannt ist, strncmp nutzen
}
Code:
char *irgendwas(char *etwas){
char *buffer;
//vorausgesetzt, dass etwas ein String ist, also mit '\0' abgeschlossen
int length = strlen(etwas);
buffer = malloc(length*sizeof(char));
strcpy(buffer, etwas);
return buffer;
}
das Beispiel ist eher sinnlos, aber so siehst du mal ungefähr wie man in c mit so etwas umgehen kann. alle str Funktionen die String.h liefert fordern einen gültigen String, wenn du in strlen z.b. einfach ein char array rein gibst ohne '\0' oder mit mehreren '\0', dann stürzt entweder dein Programm ab oder du hast nicht den ganzen teil den du haben wolltest.
für allgemeines byte-kopieren o.ä. gibt es Funktionen wie memcmp, memncmp, memcpy, memncpy,... welche byteweise arbeiten und ignorieren was der Inhalt ist.
|
|
|
06/30/2016, 23:15
|
#6
|
elite*gold: 0
Join Date: May 2015
Posts: 700
Received Thanks: 444
|
Code:
buffer = malloc(length*sizeof(char));
Du hast das +1 für die \0 vergessen :P
Code:
char *test = "test";
Das ist dann aber etwas anderes. Hier zeigt test ins .rodata, bei einem
Code:
char test[5] = "test";
wird "test\0" auf dem Stack abgelegt und test zeigt entsprechend dort hin.
Folglich führt
bei deiner Variante zur Segfault, während das bei der zweiten Variante funktioniert.
"Grundstätzlich" würde ich also nicht sagen, das kommt eher darauf an, was er denn dann mit dem String machen möchte.
|
|
|
 |
Similar Threads
|
Startparameter prüfen
05/14/2012 - C/C++ - 10 Replies
Huhu,
ich wolte mein programm überprüfen lassen ob er mit einem bestimmten parameter gestartet wurde. soweit so gut hab ich das halbwegs gemacht, nur funktioniert das nicht gescheit
hoffe um hilfe :)
for(int i = 1; i < argc; i++){
if(argv != "lampe"){
MessageBoxA(0, "Execute the launcher", "Error", MB_ICONERROR);
ExitProcess(1);
}
|
PSN-Code prüfen
12/21/2011 - Off Topic - 2 Replies
Hallo,
ich habe hier vor mir einen PSN-Code liegen aber weiß leider nicht, wofür er ist bzw. welchen Wert er hat.
Weiß einer, wie ich das prüfen kann ohne eine Playstation zu haben?
Thxxx
|
DLL auf inject prüfen
05/16/2011 - AutoIt - 10 Replies
Hi,
ist es irgendwie möglich, ob eine spezielle DLL in einen spezifischen Prozess injected wurde?
Speziell geht es mir um den Hack http://www.elitepvpers.com/forum/wow-exploits-hacks -tools-macros/1005654-wowext-xyz-hack-mit-teleport -features.html und die dazugehörige WExt.dll.
|
sql-injection prüfen
03/10/2011 - General Coding - 3 Replies
hey habe gelesen, wie man prüfen kann, ob eine webseite gegen sqlinjection sicher ist.
da steht man soltle z.b. beim login in der adresszeile z.b. &user=test
einfach schreiben &user=test' also mit nem anführungszeichen.
da aber kaum ne webseite login über get macht habe ich einfach n postrequest gesendet halt auch mit &user=test'
es hieß, dass es wenn die seite nicht gg sqlinjection geschützt ist ein fehler kommen sollte.
habs auf eigener webseite probiert (also auf einer, wo ich in...
|
Sicherheit prüfen
06/08/2006 - Technical Support - 0 Replies
Hallo,
ich habe auf meinem Webblog einen Passwortgeschützten Bereich installiert. Jetzt möchte ich die Sicherheit prüfen und benötige ein Programm, dass per Wordlist nur ein Passwort ausprobiert KEINEN username.
Ich habe nämlich keinen Loginbereich mit username und pass sondern einfach nur ein Passwortfeld.
Hier der Quelltext, hab mal geprüft und keine Passwortsource gefunden. Sicher?
<html> <head>
<title>cursusnovus - Weblog @ myblog.de</title>
<meta http-equiv="Content-Type"...
|
All times are GMT +1. The time now is 16:20.
|
|