Bei der Übergabe von Zeigern Stacküberlauf?

04/04/2011 - 13:35 von Alexander Ausserstorfer | Report spam
Hallo,

ich habe ein kleines Problem mit meinem Programm. Wenn man "MAX_LEN"
zu groß macht (2000000), bricht das Programm ab. Scheinbar kann der
Inhalt des Zeigers "zliste" in der Hauptfunktion "main" dann nicht
mehr an die Funktion "einlesen" übergeben werden, wenn MAX_LEN zu groß
wird.

Warum ist das so und wie kann man das umgehen?

Hier das vollstàndige Programm:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>

#pragma warning (disable:4996)
#define MAX_LEN 2000 // Maximale Anzahl der Zeichen für Bezeichner

struct teil_typ{
char name[MAX_LEN];
long nummer;
int anzahl;
};

int ln=0;

struct teil_typ *einlesen(struct teil_typ *zliste)
{
char name[MAX_LEN];
long nummer;
int anzahl;
struct teil_typ *backup;
zliste=(struct teil_typ *) calloc(1,sizeof(struct teil_typ));
if (zliste==NULL)
{
printf("Nicht genuegend HEAP vorhanden!!");
free(zliste);
exit(-1);
}

int h=sizeof(struct teil_typ);
do {
printf("%d. Bauteil",(ln+1));
printf(" - Bezeichnung (Ende mit \"0\"): ");
fflush(stdout);
scanf("%s",&name);
if (name[0]=='0') {printf(""); return(zliste);}
printf(" - Nummer: ");
fflush(stdout);
scanf("%ld",&nummer);
printf(" - Bedarf: ");
fflush(stdout);
scanf("%d",&anzahl);
strcpy(zliste[ln].name,name);
zliste[ln].nummer=nummer;
zliste[ln].anzahl=anzahl;
++ln;
backup=zliste;
zliste=(struct teil_typ *) realloc(zliste,h*(ln+1));
if (backup!=zliste) printf("HEAP wurde verschoben!!");
} while (1);
return(zliste);
}

void Ausgabe_Liste(struct teil_typ *zliste)
{
int i;
printf("Pos. Artikelbezeichnung Nummer Bedarf");
printf("");
for (i=0; i<41; i++) printf("_");
for (i=0; i<ln; i++)
{
int h;
h=sizeof(struct teil_typ);
printf("%d %20s %5ld %4d",i
+1,zliste[i].name,zliste[i].nummer,zliste[i].anzahl);
}
return;
}


void system_init()
{
system ("color F0");
}

void main()
{
struct teil_typ *zliste=NULL;
system_init();
system ("cls");
printf(" Artikel eingeben/Bauteilliste
ausgeben");
printf("
=");
printf(" (max_l%cnge= %d)",
132,MAX_LEN);
printf("");
// -- an dieser Stelle gibt
es Probleme, wenn MAXLEN zu groß ist
zliste=einlesen(zliste);
//
if (ln!=0) Ausgabe_Liste(zliste);
free(zliste);
printf("");
printf("");
return;
}

Danke für jede Hilfe!

Alex'
 

Lesen sie die antworten

#1 usenet
04/04/2011 - 14:35 | Warnen spam
Alexander Ausserstorfer wrote:
Hallo,

ich habe ein kleines Problem mit meinem Programm. Wenn man "MAX_LEN"
zu groß macht (2000000), bricht das Programm ab. Scheinbar kann der
Inhalt des Zeigers "zliste" in der Hauptfunktion "main" dann nicht
mehr an die Funktion "einlesen" übergeben werden, wenn MAX_LEN zu groß
wird.

Warum ist das so und wie kann man das umgehen?



[...]
struct teil_typ *einlesen(struct teil_typ *zliste)
{
char name[MAX_LEN];


[...]

Wenn MAX_LEN zu groß ist, dann belegt diese lokale Variable einfach zu
viel Stack. Mit der Übergabe von Zeigern hàngt Dein Problem nicht zusammen.
Was man machen kann, ist generell, so große Arrays nicht auf dem Stack
sondern auf dem Heap anzulegen (Details von Deinem Code habe ich nicht
angesehen, insbesondere nicht, ob Du die lokale Variable überhaupt brauchst,
oder direkt in ein auf dem Heap liegendes teil_typ-Objekt einlesen
könntest.

Zur Benutzereingabe habe ich gesehen, dass Du 'scanf("%s",...)' verwendest.
Das sollte man vermeiden, weil das am ersten Leerzeichen aufhört, Daten zu
übergeben, aber bei vielen Betriebssystemen erst zurückkehrt, wenn der
Benutzer die Eingabetaste drückt. Du solltest stattdessen gets verwenden, um
dieses Problem zu umgehen. Und statt gets solltest Du fgets verwenden, da
diese Funktion auch gesagt bekommt, wie viele Zeichen sie einlesen darf,
ohne fremden Speicher zu überschreiben.

Gruß,
Michael Karcher

Ähnliche fragen