Thread View: de.comp.lang.c++
10 messages
10 total messages
Started by Kaspar Landsberg
Wed, 01 Nov 1995 07:20
Schlechte Eingabemethode?
Author: Kaspar Landsberg
Date: Wed, 01 Nov 1995 07:20
Date: Wed, 01 Nov 1995 07:20
49 lines
2132 bytes
2132 bytes
Moin,
beim Folgenden vermute ich, dass ich recht habe, bin mir jedoch nicht
ganze sicher. Daher frage ich lieber mal nach... :-)
// bsp.cc - kleines Beispielprogramm
#include <iostream.h>
int main(void)
{
cout << "\nName: ";
char *eingabe = new char; // eingabe zeigt jetzt auf Speicherplatz
// von *einem* (1 Zeichen) char-Objekt
cin >> eingabe; // Benutzer gibt z.B. "Kaspar" ein (ohne " ")
cout << "Ergebnis: " << eingabe << "\n";
return 0;
}
So, der Knackpunkt liegt bei cout [...] << eingabe. Eigentlich wird nur
die Adresse von eingabe ausgegeben, der auf ein char Objekt mit einem
Zeichen zeigt. Da hier aber cout benutzt wird, wandelt es die Adresse
automatisch in das Zeichen um, dessen Adresse von eingabe repraesentiert
wird. Nun geht macht aber cout solange weiter, bis auf auf das Nullzeichen
trifft ('\0'). Das heisst also, dass das obige Programm "hinhaut". Denn es
gibt (im obigen Falle) "Kaspar" und nicht nur "K" aus.
Und nun zur eigentlichen Frage: Der Compiler hat eigentlich fuer eingabe
nur Speicherplatz fuer ein Char-Objekt von *einem* Zeichen bereitgestellt.
Daher wird doch, falls mehr als ein Zeichen eingegeben wird (z.b.
"Kaspar") mehr Speicher benutzt, als eigentlich vom Compiler
vorhergesehen, bzw. bereitgestellt, so dass eventuell schon besetzter
Speicherplatz einfach durch die Eingabe von "Kaspar" bzw. von "aspar"
ueberschrieben wird, oder??
Wenn ja, dann sollte man also derartige Methoden lieber ganz schnell
vergessen, nehme ich kann...
PS Fuer "char *eingabe = new char" haette man (IMO) auch einfach nur
"char *eingabe" nehmen koennen.
Danke,
Kaspar
--
Kaspar Landsberg | "Ich denke, also bin ich hier falsch."
kl@kl.in-berlin.de | = Unbekannt =
Re: Schlechte Eingabemethode?
Author: Harald Fuchs
Date: Thu, 02 Nov 1995 12:41
Date: Thu, 02 Nov 1995 12:41
31 lines
2305 bytes
2305 bytes
kl@kl.in-berlin.de (Kaspar Landsberg) writes: KL> Und nun zur eigentlichen Frage: Der Compiler hat eigentlich fuer eingabe KL> nur Speicherplatz fuer ein Char-Objekt von *einem* Zeichen bereitgestellt. KL> Daher wird doch, falls mehr als ein Zeichen eingegeben wird (z.b. KL> "Kaspar") mehr Speicher benutzt, als eigentlich vom Compiler KL> vorhergesehen, bzw. bereitgestellt, so dass eventuell schon besetzter KL> Speicherplatz einfach durch die Eingabe von "Kaspar" bzw. von "aspar" KL> ueberschrieben wird, oder?? Richtig. KL> Wenn ja, dann sollte man also derartige Methoden lieber ganz schnell KL> vergessen, nehme ich kann... Geht nicht. Die durchgängige Behandlung von char* als nullterminierte Strings kommt aus der C-Tradition. Auch wenn im neuen Standard meistens eine String-Klasse verwendet wird, so wird es dennoch Jahre dauern, bis diese Fehlerquelle trockengelegt ist. Übrigens gibt es bei den istreams für sowas die Funktion setw(). KL> PS Fuer "char *eingabe = new char" haette man (IMO) auch einfach nur KL> "char *eingabe" nehmen koennen. Nicht unbedingt, weil dadurch die Adresse keinen gültigen Anfangswert hätte (es sei denn, "eingabe" wäre eine globale Variable). In Deinem Beispiel zeigt eingabe aber tatsächlich in den Heap und dürfte dadurch die Hauptspeicherverwaltung durcheinander bringen. Wenn eingabe dagegen woanders hinzeigt, bekommt man oft "Memory fault - core dumped", und das ist ja viel weniger interessant :-)
Re: Schlechte Eingabemethode?
Author: Uwe Behrens
Date: Thu, 02 Nov 1995 14:29
Date: Thu, 02 Nov 1995 14:29
74 lines
3165 bytes
3165 bytes
In article <5x0NrSGKhjB@kl.in-berlin.de>, kl@kl.in-berlin.de (Kaspar Landsberg) writes:
|> Moin,
Moin,
|>
|> beim Folgenden vermute ich, dass ich recht habe, bin mir jedoch nicht
|> ganze sicher. Daher frage ich lieber mal nach... :-)
Kommt darauf womit Du recht haben willst ...
|>
|> // bsp.cc - kleines Beispielprogramm
|>
|> #include <iostream.h>
|>
|> int main(void)
|> {
|> cout << "\nName: ";
|> char *eingabe = new char; // eingabe zeigt jetzt auf Speicherplatz
|> // von *einem* (1 Zeichen) char-Objekt
|> cin >> eingabe; // Benutzer gibt z.B. "Kaspar" ein (ohne " ")
|> cout << "Ergebnis: " << eingabe << "\n";
|> return 0;
|> }
|>
[ grosses Wundern, warum der Compiler zulaesst, dass mehr als ein Zeichen
eingegeben wird und das Programm die ganze Eingabe ausgibt, obwohl zuwenig
Platz da ist. ]
|> Und nun zur eigentlichen Frage: Der Compiler hat eigentlich fuer eingabe
|> nur Speicherplatz fuer ein Char-Objekt von *einem* Zeichen bereitgestellt.
|> Daher wird doch, falls mehr als ein Zeichen eingegeben wird (z.b.
|> "Kaspar") mehr Speicher benutzt, als eigentlich vom Compiler
|> vorhergesehen, bzw. bereitgestellt, so dass eventuell schon besetzter
|> Speicherplatz einfach durch die Eingabe von "Kaspar" bzw. von "aspar"
|> ueberschrieben wird, oder??
Ja. Das es trotzdem klappt,kann diverse Gruende haben, prompt faellt mir ein:
Es wird nicht ein Byte (char) sondern mehrere (z.B. 8) alloziert
weil das dem Speicherlayout besser entspricht. Dann hast Du eventuell
genug Platz. Portierbar ist das nicht.
Du hast einfach Glueck gehabt. Dort wo cin hingeschrieben hat,
stand einfach nichts wichtiges. Das ist auch nicht portierbar.
Vielleicht gibt's noch andere Gruende? (Spezialisten vor)
|> Wenn ja, dann sollte man also derartige Methoden lieber ganz schnell
|> vergessen, nehme ich kann...
Die Methode, einen Stream in einen Bereich schreiben zu lassen, der die
Daten nicht halten kann, die solltest Du ganz schnell vergessen. Eigentlich
haette Dir die Idee gar nicht kommen sollen ;-)
|> PS Fuer "char *eingabe = new char" haette man (IMO) auch einfach nur
|> "char *eingabe" nehmen koennen.
|>
Das waere wahrscheinlich in (fast) jedem Fall abgestuerzt, was waere wenn
(eingabe == 0) ?
|>
|> Danke,
|>
|> Kaspar
--
_______________________________________________________________________________
Uwe Behrens <behrens@acm.org> (aka <uwe@mevis.uni-bremen.de>)
``Black Holes are where God is dividing by zero.''
Re: Schlechte Eingabemethode?
Author: Bernd Eggink
Date: Thu, 02 Nov 1995 16:54
Date: Thu, 02 Nov 1995 16:54
70 lines
3127 bytes
3127 bytes
Kaspar Landsberg (kl@kl.in-berlin.de) wrote:
> Moin,
> beim Folgenden vermute ich, dass ich recht habe, bin mir jedoch nicht
> ganze sicher. Daher frage ich lieber mal nach... :-)
> // bsp.cc - kleines Beispielprogramm
> #include <iostream.h>
> int main(void)
> {
> cout << "\nName: ";
> char *eingabe = new char; // eingabe zeigt jetzt auf Speicherplatz
> // von *einem* (1 Zeichen) char-Objekt
> cin >> eingabe; // Benutzer gibt z.B. "Kaspar" ein (ohne " ")
> cout << "Ergebnis: " << eingabe << "\n";
> return 0;
> }
> So, der Knackpunkt liegt bei cout [...] << eingabe. Eigentlich wird nur
Nein, er liegt bei "cin >> eingabe". Schon wenn der Benutzer nur ein
Zeichen eingibt, werden 2 im Speicher abgelegt - das eingegebene und die
obligate '\0'. Du ueberschreibst also wild irgendwelche Speicherbereiche.
> die Adresse von eingabe ausgegeben, der auf ein char Objekt mit einem
> Zeichen zeigt. Da hier aber cout benutzt wird, wandelt es die Adresse
> automatisch in das Zeichen um, dessen Adresse von eingabe repraesentiert
Nein, ostreams wandeln nicht char* in Zeichen um, sondern geben alle
Zeichen ab der angegebenen Adresse aus, bis zur '\0'.
> wird. Nun geht macht aber cout solange weiter, bis auf auf das Nullzeichen
> trifft ('\0'). Das heisst also, dass das obige Programm "hinhaut". Denn es
> gibt (im obigen Falle) "Kaspar" und nicht nur "K" aus.
> Und nun zur eigentlichen Frage: Der Compiler hat eigentlich fuer eingabe
> nur Speicherplatz fuer ein Char-Objekt von *einem* Zeichen bereitgestellt.
> Daher wird doch, falls mehr als ein Zeichen eingegeben wird (z.b.
> "Kaspar") mehr Speicher benutzt, als eigentlich vom Compiler
> vorhergesehen, bzw. bereitgestellt, so dass eventuell schon besetzter
> Speicherplatz einfach durch die Eingabe von "Kaspar" bzw. von "aspar"
> ueberschrieben wird, oder??
Ja, s.o.
> Wenn ja, dann sollte man also derartige Methoden lieber ganz schnell
> vergessen, nehme ich kann...
Nein, man muss nur hinreichend viel Speicher zur Verfuegung stellen, z.B.
char eingabe[128]; // oder char *eingabe = new char[128];
//...
cin >> eingabe;
cout << "Ergebnis: " << eingabe << "\n";
> PS Fuer "char *eingabe = new char" haette man (IMO) auch einfach nur
> "char *eingabe" nehmen koennen.
Nein, das schon gar nicht (undefinierter Zeigerwert)!
Gruss
Bernd
--
+----------------------------------+
| Bernd Eggink |
| Rechenzentrum Uni Hamburg |
| admin@rzaix13.rrz.uni-hamburg.de |
+----------------------------------+
Re: Schlechte Eingabemethode?
Author: Benjamin Baermann
Date: Fri, 03 Nov 1995 10:15
Date: Fri, 03 Nov 1995 10:15
17 lines
1202 bytes
1202 bytes
In <5x0NrSGKhjB@kl.in-berlin.de> kl@kl.in-berlin.de (Kaspar Landsberg) writes:
> char *eingabe = new char; // eingabe zeigt jetzt auf Speicherplatz
> // von *einem* (1 Zeichen) char-Objekt
> cin >> eingabe; // Benutzer gibt z.B. "Kaspar" ein (ohne " ")
> cout << "Ergebnis: " << eingabe << "\n";
>Wenn ja, dann sollte man also derartige Methoden lieber ganz schnell
>vergessen, nehme ich kann...
Ja, stimmt. Deine Folgerungen sind korrekt.
Gruesse, Benni
--
benni@informatik.uni-frankfurt.de|http://www.uni-frankfurt.de/gnomic/hello.html
"Deshalb, Leute, die glauben, dass Computer werden nicht koennen, wie
Menschen zu denken, auch glaubt nicht in Maschine-Uebersetzung."
Re: Schlechte Eingabemethode?
Author: Martin Prange
Date: Tue, 07 Nov 1995 16:12
Date: Tue, 07 Nov 1995 16:12
66 lines
3316 bytes
3316 bytes
In article <47akku$99n@p235.informatik.uni-Bremen.de> uwe@mathematik.uni-Bremen.de (Uwe Behrens) writes:
In article <5x0NrSGKhjB@kl.in-berlin.de>, kl@kl.in-berlin.de (Kaspar Landsberg) writes:
|>
|> // bsp.cc - kleines Beispielprogramm
|>
|> #include <iostream.h>
|>
|> int main(void)
|> {
|> cout << "\nName: ";
|> char *eingabe = new char; // eingabe zeigt jetzt auf Speicherplatz
|> // von *einem* (1 Zeichen) char-Objekt
|> cin >> eingabe; // Benutzer gibt z.B. "Kaspar" ein (ohne " ")
|> cout << "Ergebnis: " << eingabe << "\n";
|> return 0;
|> }
|>
[ grosses Wundern, warum der Compiler zulaesst, dass mehr als ein Zeichen
eingegeben wird und das Programm die ganze Eingabe ausgibt, obwohl zuwenig
Platz da ist. ]
|> Und nun zur eigentlichen Frage: Der Compiler hat eigentlich fuer eingabe
|> nur Speicherplatz fuer ein Char-Objekt von *einem* Zeichen bereitgestellt.
|> Daher wird doch, falls mehr als ein Zeichen eingegeben wird (z.b.
|> "Kaspar") mehr Speicher benutzt, als eigentlich vom Compiler
|> vorhergesehen, bzw. bereitgestellt, so dass eventuell schon besetzter
|> Speicherplatz einfach durch die Eingabe von "Kaspar" bzw. von "aspar"
|> ueberschrieben wird, oder??
Ja. Das es trotzdem klappt,kann diverse Gruende haben, prompt faellt mir ein:
Es wird nicht ein Byte (char) sondern mehrere (z.B. 8) alloziert
weil das dem Speicherlayout besser entspricht. Dann hast Du eventuell
genug Platz. Portierbar ist das nicht.
Du hast einfach Glueck gehabt. Dort wo cin hingeschrieben hat,
stand einfach nichts wichtiges. Das ist auch nicht portierbar.
Vielleicht gibt's noch andere Gruende? (Spezialisten vor)
Hmm.
Bei solch einem kleinen Programm, wo bis auf cin, etc. noch kein
malloc (resp. new) gemacht wurde, ist es ALLERHOECHSTWAHRSCHEINLICH,
dass es an DIESER stelle NICHT knallt ( .. aber beim darauffolgenden
free (resp. delete), da die Speicherplatzverwaltung inkonsistent
geworden ist.
mein Rat:
Nimm doch einfach istrstream, dann bist Du den Aerger mit der
Speicheplatzverwaltung los.
BTW: Die in diesem thread geaeusserte Idee, doch einfach char[128] zu
nehmen, ist boese, denn es findet sich immer ein Idiot, der das
128. Zeichen eingibt...
Folge: macht Stack kaputt!
also: boese.
Martin Prange (prange@cs.tu-berlin.de) ////////////////////////////////////////
Member of the ALMAP Team at Alcatel SEL Berlin //// Home: +49 30 7848958 //////
//// Work: +49 30 7002 - 0 (OP) /
Re: Schlechte Eingabemethode?
Author: Bernd Eggink
Date: Thu, 09 Nov 1995 10:07
Date: Thu, 09 Nov 1995 10:07
40 lines
1748 bytes
1748 bytes
Martin Prange (prange@cs.tu-berlin.de) wrote: [ ... ] > mein Rat: > Nimm doch einfach istrstream, dann bist Du den Aerger mit der > Speicheplatzverwaltung los. Kein guter Rat. istrstream braucht einen Puffer, aus dem gelesen wird, und das ist genau die Eingabezeilei. D.h. istrstream tut nur vollkommen Ueberfluessiges und an dem Speicherproblem aendert sich nicht das geringste. > BTW: Die in diesem thread geaeusserte Idee, doch einfach char[128] zu > nehmen, ist boese, denn es findet sich immer ein Idiot, der das > 128. Zeichen eingibt... > Folge: macht Stack kaputt! > also: boese. Mitnichten. Unter DOS z.B. ist es ueberhaupt nicht moeglich, mehr als 128 Zeichen pro Zeile einzugeben. Wer 128 zu niedrig findet, kann ja meinetwegen 1024 nehmen. Ausserdem hat man die Moeglichkeit, vorher width=Arraylaenge zu setzen, dann gibt es gar kein Problem mehr: char zeile[333]; cin >> setw(sizeof zeile) >> zeile; Es werden jetzt maximal 332 Zeichen gelesen. Gruss Bernd -- +----------------------------------+ | Bernd Eggink | | Rechenzentrum Uni Hamburg | | admin@rzaix13.rrz.uni-hamburg.de | +----------------------------------+
Re: Schlechte Eingabemethode?
Author: Kaspar Landsberg
Date: Thu, 09 Nov 1995 16:38
Date: Thu, 09 Nov 1995 16:38
17 lines
988 bytes
988 bytes
Tach,
die Standleitung meines Providers war vor kurzem fuer eine Weile down.
Daher sind waehrend dieser Zeit die News sozusagen ausgefallen. Nun
bemerke ich, dass auf meine Frage geantwortet wurde.
Wenn jetzt jede(r), der/die direkt geantwortet hat, mir diese Antwort
zumailen koennte, waere ich ihm/ihr sehr dankbar.
Danke,
Kaspar
--
Kaspar Landsberg | "Als erstes wollen wir mal festlegen, wer
kl@kl.in-berlin.de | hier fuehrt."
= F. Astaire =
Re: Schlechte Eingabemethode?
Author: Nico Josuttis
Date: Fri, 10 Nov 1995 17:39
Date: Fri, 10 Nov 1995 17:39
33 lines
1684 bytes
1684 bytes
In article <47o0gl$e7n@news.cs.tu-berlin.de>,
Martin Prange <prange@cs.tu-berlin.de> wrote:
> |> #include <iostream.h>
> |>
> |> int main(void)
> |> {
> |> cout << "\nName: ";
> |> char *eingabe = new char; // eingabe zeigt jetzt auf Speicherplatz
> |> // von *einem* (1 Zeichen) char-Objekt
> |> cin >> eingabe; // Benutzer gibt z.B. "Kaspar" ein (ohne " ")
> |> cout << "Ergebnis: " << eingabe << "\n";
> |> return 0;
> |> }
> |>
>
> [ grosses Wundern, warum der Compiler zulaesst, dass mehr als ein Zeichen
> eingegeben wird und das Programm die ganze Eingabe ausgibt, obwohl zuwenig
> Platz da ist. ]
Na, wenn man ihm sagt, er soll einen String einlesen
(der Typ von eingabe ist naemlich "char*"), dann tut er es auch.
Also besser den char zum Einlesen uebergeben:
cin >> *eingabe;
Im uebrigen kann man nach dem neuen Standard Strings auch so
einlesen, dass sie dabei automatisch wachsen.
--
Nico address: BREDEX GmbH, Nicolai Josuttis
email: nico@bredex.de Fallersleber-Tor-Wall 23
phone: +49 531 24330-0 D-38100 Braunschweig
fax: +49 531 24330-99 Germany
Re: Schlechte Eingabemethode?
Author: Nico Josuttis
Date: Tue, 14 Nov 1995 15:49
Date: Tue, 14 Nov 1995 15:49
29 lines
1490 bytes
1490 bytes
In article <wm1GlMD37Caez3@a-schoep.amtrash.comlink.de>,
Andreas Schoepf <A.Schoepf@AmTrash.comlink.de> wrote:
>besser ist folgendes:
>
>#include <iostream.h>
>#include <stream.h>
>int main(void)
>{
> char input_line[80];
> cout << "\nName: ";
> cin >> input_line;
> char *eingabe = new char[strlen(input_line)+1];// wegen der terminierenden
> // 0 ein Zeichen mehr
> strcpy(*eingabe,input_line);
> cout << "Ergebnis: " << *eingabe << "\n";
> return 0;
>}
Und da ist wieder der ach so beliebte C-Fehler, naemlich anzunehmen, dass
eine Zeile hoechstens 79 (? wieso nicht 80 ?) Zeichen lang sein kann.
Also um den Absturz zu vermeiden, noch besser:
> cin >> setw(80) >> input_line;
oder
> cin >> setw(sizeof(input_line)) >> input_line;
--
Nico address: BREDEX GmbH, Nicolai Josuttis
email: nico@bredex.de Fallersleber-Tor-Wall 23
phone: +49 531 24330-0 D-38100 Braunschweig
fax: +49 531 24330-99 Germany
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads