Programm stürzt beim Zugriff auf Array ab

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
Orioner
Beiträge: 102
Registriert: Mo Dez 10, 2012 10:52 am

Programm stürzt beim Zugriff auf Array ab

Beitrag von Orioner » So Dez 20, 2015 1:39 pm

Hallo!

Für ein kleines Programmierprojekt geriet ich jüngst in die Verlegenheit ein Array mit mehr als 261.077 Array-Elementen zu deklarieren, genauer gesagt, ein zweidimensionales Array mit 601x601 Feldern. Jedoch stürzt das Programm bei jedem Versuch auf ein solches Array zuzugreifen ab. Die Grenze scheint hier bei 261.077 Elementen zu liegen. Eins mehr und ein Absturz ist im wahrsten Sinne des Wortes "vorprogrammiert".

Gibt es in C eine Grenze für die Anzahl an Array-Elementen? Wenn ja, habe ich von dieser bisher noch nie gehört oder gelesen. Welche Möglichkeit hätte ich, diese Begrenzung zu umgehen. Wäre "dynamische Speicherallokation" eine Lösung? Oder Vektoren?

nouseforname
Beiträge: 236
Registriert: Do Feb 10, 2011 6:31 pm

Re: Programm stürzt beim Zugriff auf Array ab

Beitrag von nouseforname » So Dez 20, 2015 4:02 pm

Hi,

wie wäre es wenn Du die betreffende Deklaration, Definition und den Zugriff als Code aufzeigst? Dann lässt sich auch besser sagen ob und welche Alternativen sich anbieten würden.

Orioner
Beiträge: 102
Registriert: Mo Dez 10, 2012 10:52 am

Re: Programm stürzt beim Zugriff auf Array ab

Beitrag von Orioner » So Dez 20, 2015 5:32 pm

Hätte ich nicht gedacht, dass das hilfreich ist, aber gerne doch:

Code: Alles auswählen

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

#ifdef __bool_true_false_are_defined
#undef true
#undef false
#undef bool
#define true 1
#define false 0
#define bool char
#endif

#if( __BORLANDC__ <= 0x460 ) || !defined( __cplusplus )
typedef enum { false, true } bool;
#endif

/* ... übersetzt unter Linux/UNIX? */
#ifdef __unix__
	#include <termios.h>
	#include <unistd.h>

static struct termios new_io;
static struct termios old_io;

int cbreak( int fd ) {
   /* Sichern unseres Terminals */
   if(( tcgetattr( fd, &old_io )) == -1 ) { return -1; }
   new_io = old_io;
   /* Wir verändern jetzt die Flags für den cbreak-Modus. */
   new_io.c_lflag = new_io.c_lflag & ~( ECHO|ICANON );
   new_io.c_cc[ VMIN ] = 1;
   new_io.c_cc[ VTIME ]= 0;
   /* Jetzt setzen wir den cbreak-Modus */
   if(( tcsetattr( fd, TCSAFLUSH, &new_io )) == -1 ) { return -1; }
   return 1;
}

int getch( void ) {
	int c;
	if( cbreak( STDIN_FILENO ) == -1 ) {
		printf( "Fehler bei der Funktion cbreak ... \n" );
		exit( EXIT_FAILURE );
	}
	c = getchar();
	/* alten Terminal-Modus wiederherstellen */
	tcsetattr( STDIN_FILENO, TCSANOW, &old_io );
	return c;
}

/* ... oder wird das Programm unter MS-Windows übersetzt? */
#elif __WIN32__ || _MSC_VER || __MS_DOS__
	#include <conio.h>
#endif

int main( void ) {
	int i;
	int board[261078];
	for( i = 0; i <= 261077; i++ ) { board[i] = 0; }
	return EXIT_SUCCESS;
}
Das ist die komplette Quelltext-Datei. Alles oberhalb von "int main(void)" kann sicher ignoriert werden. Es dient dazu, "getch" als Befehl und "bool" als Variablentyp verfügbar zu machen.

Benutzeravatar
cloidnerux
Moderator
Beiträge: 3125
Registriert: Fr Sep 26, 2008 4:37 pm
Wohnort: Ram (Gibts wirklich)

Re: Programm stürzt beim Zugriff auf Array ab

Beitrag von cloidnerux » So Dez 20, 2015 6:27 pm

Für ein kleines Programmierprojekt geriet ich jüngst in die Verlegenheit ein Array mit mehr als 261.077 Array-Elementen zu deklarieren, genauer gesagt, ein zweidimensionales Array mit 601x601 Feldern. Jedoch stürzt das Programm bei jedem Versuch auf ein solches Array zuzugreifen ab. Die Grenze scheint hier bei 261.077 Elementen zu liegen. Eins mehr und ein Absturz ist im wahrsten Sinne des Wortes "vorprogrammiert".
Gerade mal bei mir Ausprobiert: Windows 7 x64, gcc 4.8.1
Das Programm stürzt direkt beim Aufruf ab, wenn das Array irgendwo größer als 300k ist, also gibt es hier wohl eine gewisse Systemabhängigkeit, Page-grenzen oder was auch immer.
Mit malloc funktioniert es problemlos:

Code: Alles auswählen

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

int main()
{
	int i;
	int * array = (int*)malloc(1000000 * sizeof(int));
	for(i = 0; i < 1000000; i++)
	{
		if((i % 10) == 0)
			printf("%d", i);
		array[i] = 0;
	}	
	printf("Success");
}
Redundanz macht wiederholen unnötig.
quod erat expectandum

Orioner
Beiträge: 102
Registriert: Mo Dez 10, 2012 10:52 am

Re: Programm stürzt beim Zugriff auf Array ab

Beitrag von Orioner » So Dez 20, 2015 8:19 pm

Das ist aber eine dynamische Allokation/Alloziierung, richtig? Vielen Dank. Ich dachte schon, ich spinne!

Orioner
Beiträge: 102
Registriert: Mo Dez 10, 2012 10:52 am

Re: Programm stürzt beim Zugriff auf Array ab

Beitrag von Orioner » Di Dez 22, 2015 1:07 pm

Wie ich nun las, ist es auch möglich, dynamischen Speicher im Stack zu reservieren, mit einer Funktion die in keinem ANSI-C-Standard enthalten ist: alloca()

Sie wird verwendet wie malloc(), aber ihr Speicher wird bei Verlassen des Scopes (Gültigkeitsbereichs) automatisch freigegeben und darf nicht mit free() (wie bei malloc()) freigegeben werden.

Weitere (knappe) Informationen finden sich hier: http://openbook.rheinwerk-verlag.de/c_v ... ng_009.htm

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Programm stürzt beim Zugriff auf Array ab

Beitrag von Xin » Di Dez 22, 2015 4:50 pm

Ich hatte vor knapp 10 Jahren ein Programm, welches beim Zugriff auf das 65000 Element anfing Schwierigkeiten zu machen.
Bei Windows gibt es da wohl einige "Besonderheiten".

Von alloca weiß ich nichts. Ich empfehle Dir eher Dich in Richtung C++ zu bewegen und dir shared_ptr bzw. unique_ptr anzusehen.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

mfro
Beiträge: 346
Registriert: Mi Jan 16, 2013 4:58 pm

Re: Programm stürzt beim Zugriff auf Array ab

Beitrag von mfro » Di Dez 22, 2015 6:59 pm

Orioner hat geschrieben:...ist es auch möglich, dynamischen Speicher im Stack zu reservieren, mit einer Funktion die in keinem ANSI-C-Standard enthalten ist: alloca()...
alloca() mit großen Arrays zu benutzen, ist keine gute Idee (das gleiche gilt für die C99 "variable length arrays", weil die dieselbe Funktionalität nutzen). Der Stack _muß_ dann groß genug sein. Wenn nicht -> crash.

Außerdem sollte man alloca() nicht unbedingt in inline-Kandidaten verwenden, weil man sich damit u.U. den potentiellen Stacküberlauf im ganzen Programm verteilt.
It's as simple as that. And remember, Beethoven wrote his first symphony in C.

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Programm stürzt beim Zugriff auf Array ab

Beitrag von Xin » Di Dez 22, 2015 7:39 pm

mfro hat geschrieben:
Orioner hat geschrieben:...ist es auch möglich, dynamischen Speicher im Stack zu reservieren, mit einer Funktion die in keinem ANSI-C-Standard enthalten ist: alloca()...
alloca() mit großen Arrays zu benutzen, ist keine gute Idee (das gleiche gilt für die C99 "variable length arrays"...
Da alloca für Arrays gedacht ist, aber die maximale Größe vom Stack abhängt, dessen Größe sich ebenfalls laufend verändert, klingt das für mich nach einem Bug mit Killer-Potential.
Wenn man den Bug nicht nachvollziehen kann, weil man nicht exakt die richtigen Daten hat, stirbt die Software. Gut zu wissen, falls ich mal alloca zu Gesicht bekomme.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Antworten