Re: strcat unter FreeBSD

From: Oliver Fromme <olli(at)dorifer.heim3.tu-clausthal.de>
Date: Tue, 27 Jul 1999 23:49:37 +0200 (CEST)

Klaus Herrmann wrote in list.de-bsd-questions:
> Ich will unter FreeBSD die C-Funktion "strcat" nutzen, allerdings gibt
> mir schon das folgende stückchen code einen bus error ("exited on
> signal 10"):
>
> #include <string.h>
> #include <stdio.h>
> main() {
> char* s = "Hello";
> const char* t = " World";
> s = strcat( s, t );
> printf("%s\n", s);
> return 0;
> }
>
> Ich denke nicht, dass der Fehler bei mir liegt,

Leider doch.

strcat() hängt an einen bestehenden String etwas an. Dafür,
daß dort entsprechend Speicherplatz vorhanden ist, um etwas an-
zuhängen, hat der Programmierer Sorge zu tragen. Das hast Du
in Deinem Code nicht getan.

Das strcat() überschreibt bei Dir fröhlich den Speicher hinter
dem Inhalt der Variablen s. Du mußt bedenken, daß der Compiler
beim Compilieren nur genug Platz für s reserviert, so daß der
angegebene String ("Hello") hineinpaßt, d.h. sechs Bytes (eines
pro Zeichen sowie das abschließenden Nullbyte).

Strings in C werden nicht automatisch dynamisch alloziiert.
Der Programmierer muß daher selbst sicherstellen, daß bei
Stringoperationen keine Buffer-Overflows auftreten. (Es gibt
aber diverse kleine Libs, die es dem Programmierer leichter
machen.)

Hier wäre mein Vorschlag:

    #include <string.h>
    #include <stdio.h>
    
    int
    main (int argc, char *argv[])
    {
        char s[20] = "Hello";
        char *t = " World";
    
        strcat (s, t);
        printf ("%s\n", s);
        return 0;
    }

olli(at)dao-lin-hay:/tmp> cc -Wall -ansi -pedantic -o hello hello.c
olli(at)dao-lin-hay:/tmp> ./hello
Hello World
olli(at)dao-lin-hay:/tmp>

Eleganter wäre es natürlich, man berechnet im Programm, wie
lang denn der zusammengesetzte String wird, und belegt dann
entsprechend viele Bytes dynamisch mit malloc():

    #include <string.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    int
    main (int argc, char *argv[])
    {
        char *r;
        char *s = "Hello";
        char *t = " World";
    
        r = malloc(strlen(s) + strlen(t) + 1);
        strcpy (r, s);
        strcat (r, t);
        printf ("%s\n", r);
        return 0;
    }

> ich habe extra meinen
> Uralt-Visual-C++ compiler (Version 1.00) ausgegraben, und der
> Compiliert das ganze durch und kann es ohne Probleme ausführen. Wenn
> mich mich recht erinnere, lief so was auch mal mit watcom c++ 11, den
> ich mal testhalber auf der platte hatte.

Erstens passieren unter DOS keine Zugriffsprüfungen. Zweitens
kannst Du reines Glück haben, daß er durch den Fehler keinen
"wichtigen" Speicher überschreibt. Je nachdem, wie der Compi-
ler die Objekte (Code, Stack, Variablen, Konstanten) im Spei-
cher anordnet, kann es zu unterschiedlichen Effekten kommen,
wenn man unerlaubt im Speicher herumschreibt.

> (2) (die nicht so wichtige Frage)
> Was genau ist eine PDP11 ?!?
> Da ich ja nun zur jüngsten UNIX-Generation gehöre ;) habe ich nicht so
> den überblich über die letzten 30Jahre UNIX und Computer. Ich stolpere
> aber immer wieder über diesen anscheinend lustigen Computer, z.B. in
> "fortune".

PDP-11 ist die erste 16bit-Rechnerfamilie von DEC, eingeführt
1970 mit der PDP-11/20. Im November 1971 (ich war noch kein
ganzes Jahr alt) lief darauf die "First Edition" von UNIX.
Größe und Form der Zentraleinheit entsprechen in etwa der eines
handelsüblichen Kühlschrankes.

Siehe auch: http://www.digital.com/timeline/1970.htm

Die PDP-11 hat sich jahrzehntelang enormer Beliebtheit erfreut,
sie ist vielleicht eins der langlebigsten Stückchen Hardware
überhaupt. Erst Ende 1997 hat (damals noch) DEC den Verkauf
von PDP-11-Hardware eingestellt, und Support wird immerhin noch
bis zum Jahr 2002 geleistet.

Hierzu siehe auch: http://www.digital.com/CU2902/

Es gibt übrigens einen PDP-Emulator als Freeware:
http://www.openvms.digital.com/freeware/PDP_SIM/

Gruß
   Oliver

-- 
Oliver Fromme, Leibnizstr. 18/61, 38678 Clausthal, Germany
(Info: finger userinfo:olli(at)dorifer.heim3.tu-clausthal.de)
"In jedem Stück Kohle wartet ein Diamant auf seine Geburt"
                                         (Terry Pratchett)
To Unsubscribe: send mail to majordomo(at)de.FreeBSD.org
with "unsubscribe de-bsd-questions" in the body of the message
Received on Tue 27 Jul 1999 - 23:49:50 CEST

search this site