🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: de.comp.lang.c++
10 messages
10 total messages Started by Kaspar Landsberg Wed, 01 Nov 1995 07:20
Schlechte Eingabemethode?
#700
Author: Kaspar Landsberg
Date: Wed, 01 Nov 1995 07:20
49 lines
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?
#709
Author: Harald Fuchs
Date: Thu, 02 Nov 1995 12:41
31 lines
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?
#710
Author: Uwe Behrens
Date: Thu, 02 Nov 1995 14:29
74 lines
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?
#713
Author: Bernd Eggink
Date: Thu, 02 Nov 1995 16:54
70 lines
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?
#717
Author: Benjamin Baermann
Date: Fri, 03 Nov 1995 10:15
17 lines
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?
#745
Author: Martin Prange
Date: Tue, 07 Nov 1995 16:12
66 lines
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?
#752
Author: Bernd Eggink
Date: Thu, 09 Nov 1995 10:07
40 lines
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?
#757
Author: Kaspar Landsberg
Date: Thu, 09 Nov 1995 16:38
17 lines
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?
#767
Author: Nico Josuttis
Date: Fri, 10 Nov 1995 17:39
33 lines
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?
#793
Author: Nico Josuttis
Date: Tue, 14 Nov 1995 15:49
29 lines
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