AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein [GCC 3.3.1] Compilerfehler bei Stringoperation?
Thema durchsuchen
Ansicht
Themen-Optionen

[GCC 3.3.1] Compilerfehler bei Stringoperation?

Ein Thema von d3g · begonnen am 4. Feb 2004 · letzter Beitrag vom 5. Feb 2004
Antwort Antwort
Benutzerbild von d3g
d3g

Registriert seit: 21. Jun 2002
602 Beiträge
 
#1

[GCC 3.3.1] Compilerfehler bei Stringoperation?

  Alt 4. Feb 2004, 19:52
Ich kann zwar nicht das Gefühl loswerden, dass das schon wieder einer meiner sehr blöden Fehler ist, aber irgendwie sieht das alles doch nach Compilerfehler aus.

Code:
#include <stdio.h>
#include <string.h>

void proof_of_concept(char **s) {
    int i;
    char *res = (char*)malloc(sizeof(char) * strlen(*s));
    for (i = strlen(*s) - 1; i >= 0; i--)
        res[strlen(*s) - 1 - i] = (*s)[i];
    free(*s);
    *s = res;
}

int main(void) {
    char *s = (char*)malloc(sizeof(char) * 256);
    fgets(s, 256, stdin);
    s[strlen(s) - 1] = '\0'; // remove newline
    proof_of_concept(&s);
    printf("%s\n", s);
    free(s);
    return 0;
}
Ist strlen(s) == 12 (und nur dann), sei s bespielsweise "abcdefghijkl", erhalte ich als Ergebnis zusätzlich zwei Zeichen mehr ("lkjihgfedcbaé\016"). Diese Zeichen werden in proof_of_concept bei i == 0 hinzugefügt (obwohl so viel Speicher gar nicht reseviert ist).

Code:
08048434 <proof_of_concept>:
 8048434:      55                      push  %ebp
 8048435:      89 e5                   mov   %esp,%ebp
 8048437:      83 ec 18                sub   $0x18,%esp
 804843a:      8b 45 08                mov   0x8(%ebp),%eax
 804843d:      8b 00                   mov   (%eax),%eax
 804843f:      89 04 24                mov   %eax,(%esp,1)
 8048442:      e8 e5 fe ff ff         call  804832c <_init+0x48>
 8048447:      89 04 24                mov   %eax,(%esp,1)
 804844a:      e8 bd fe ff ff         call  804830c <_init+0x28>
 804844f:      89 45 f8                mov   %eax,0xfffffff8(%ebp)
 8048452:      8b 45 08                mov   0x8(%ebp),%eax
 8048455:      8b 00                   mov   (%eax),%eax
 8048457:      89 04 24                mov   %eax,(%esp,1)
 804845a:      e8 cd fe ff ff         call  804832c <_init+0x48>
 804845f:      48                      dec   %eax
 8048460:      89 45 fc               mov   %eax,0xfffffffc(%ebp)
 8048463:      83 7d fc 00             cmpl  $0x0,0xfffffffc(%ebp)
 8048467:      79 02                   jns   804846b <proof_of_concept+0x37>
 8048469:      eb 2a                  jmp   8048495 <proof_of_concept+0x61>
 804846b:      8b 45 08                mov   0x8(%ebp),%eax
 804846e:      8b 00                   mov   (%eax),%eax
 8048470:      89 04 24                mov   %eax,(%esp,1)
 8048473:      e8 b4 fe ff ff         call  804832c <_init+0x48>
 8048478:      2b 45 fc               sub   0xfffffffc(%ebp),%eax
 804847b:      03 45 f8                add   0xfffffff8(%ebp),%eax
 804847e:      8d 48 ff               lea   0xffffffff(%eax),%ecx
 8048481:      8b 55 08                mov   0x8(%ebp),%edx
 8048484:      8b 45 fc               mov   0xfffffffc(%ebp),%eax
 8048487:      03 02                   add   (%edx),%eax
 8048489:      0f b6 00                movzbl (%eax),%eax
 804848c:      88 01                   mov   %al,(%ecx)
 804848e:      8d 45 fc               lea   0xfffffffc(%ebp),%eax
 8048491:      ff 08                   decl  (%eax)
 8048493:      eb ce                  jmp   8048463 <proof_of_concept+0x2f>
 8048495:      8b 45 08                mov   0x8(%ebp),%eax
 8048498:      8b 00                   mov   (%eax),%eax
 804849a:      89 04 24                mov   %eax,(%esp,1)
 804849d:      e8 ba fe ff ff         call  804835c <_init+0x78>
 80484a2:      8b 55 08                mov   0x8(%ebp),%edx
 80484a5:      8b 45 f8                mov   0xfffffff8(%ebp),%eax
 80484a8:      89 02                   mov   %eax,(%edx)
 80484aa:      c9                      leave
 80484ab:      c3                      ret
Kann jemand von euch aus dem Assembler-Code was erkennen (ich weiß, es ist AT&T-Syntax, aber für Profis wie euch dürfte das kein Problem darstellen, oder? )
Ist das Problem mit anderen Compilern / anderen GCC-Versionen reproduzierbar?

Danke im Voraus,
d3g

PS.
Code:
ben@picard:~$ gcc -v
Reading specs from /usr/lib/gcc-lib/i686-pc-linux-gnu/3.3.1/specs
Configured with: ../gcc-3.3.1/configure --enable-shared --prefix=/usr --enable-threads=posix --enable-languages=c,c++,objc,java --with-slibdir=/lib --enable-__cxa_atexit --enable-clocale=gnu
Thread model: posix
gcc version 3.3.1
-- Crucifixion?
-- Yes.
-- Good. Out of the door, line on the left, one cross each.
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.483 Beiträge
 
Delphi 10.1 Berlin Professional
 
#2

Re: [GCC 3.3.1] Compilerfehler bei Stringoperation?

  Alt 4. Feb 2004, 20:48
Zitat von d3g:
Ist das Problem mit anderen Compilern / anderen GCC-Versionen reproduzierbar?
Das Problem ist sogar mit dem Delphi-Compiler reproduzierbar. Auch der MSVC++ und BCB Compiler haben das Problem.
Dieses Problem nennt sich logischer Fehler.

Ein Null-terminierter String (char*) nennt sich Null-terminiert, weil er bei \0 endet. Ist kein \0 vorhanden, wird einfach bis zum nächsten \0 weitergearbeitet. Dein Fehler beginnt schon beim reservieren des Speichers. Das \0 braucht auch noch Platz. Zudem solltest du das \0 in res dann auch noch definitiv setzen, da man ja nie wissen kann ob bei der Chance 1:255 auch die 0 herauskommt.
  Mit Zitat antworten Zitat
Benutzerbild von d3g
d3g

Registriert seit: 21. Jun 2002
602 Beiträge
 
#3

Re: [GCC 3.3.1] Compilerfehler bei Stringoperation?

  Alt 5. Feb 2004, 15:47
Zitat von jbg:
Ein Null-terminierter String (char*) nennt sich Null-terminiert, weil er bei \0 endet. Ist kein \0 vorhanden, wird einfach bis zum nächsten \0 weitergearbeitet. Dein Fehler beginnt schon beim reservieren des Speichers. Das \0 braucht auch noch Platz.
Argh! Ich wusste doch, dass es wieder ein blöder Fehler ist. Ich hab in der Manpage ein kleines Wörtchen überlesen ...

Zitat:
The strlen() function calculates the length of the string s, not
including the terminating `\0' character.
Wie auch immer, danke.

[edit]Mir fällt gerade auf, dass ich dann ja noch einen zweiten Fehler gemacht habe: nicht bemerkt, dass der Ergebnisstring eigentlich leer sein sollte [/edit]
-- Crucifixion?
-- Yes.
-- Good. Out of the door, line on the left, one cross each.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:51 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz