Corrupted Stack bei Sortierverfahren

Hallo,

ich programmiere eine Zeit schon an einem Programm, welches Bubble- und Mergesort vergleicht. Dazu erzeuge ich mehrere Arrays, die mit Zufallszahlen befüllt werden, und anschließend einmal mit Bubble und dann mit Merge sortiert werden. Darum herum wird die Zeit gemessen und am Ende ausgegeben, wie lange welches Sortierverfahren benötigt hat, bzw in welchen Verhältnis der Programmaufwand besteht.

Nun ist es so, dass ich immer eine Fehlermeldung erhalte:

„C Run-Time Check Failure #2 - Stack around the variable ‚f‘ was corrupted.“

Das ist mein letztes, zu sortierende Array für den Mergesort.
Wenn ich dieses auf 1000 Felder verkleinere, wie in dem Teil davor, bekomme ich die gleiche Fehlermeldung, allerdings für das Array ‚d‘, also das Merge-Array von der Sortierung mit 1000 Feldern.

Also muss ich in einer Mergefunktion einen stackoverflow haben, nicht wahr? Ich finde aber meinen Fehler nicht. Um Hilfe wäre ich sehr dankbar!

mit Gruße,
Streuselchen

Der Code (das Hauptprogramm „main“ ist ganz unten)

#include "stdafx.h"
#include 
#include 
#include 
#include 
#include 



void dreieckstausch(int \*x, int \*y)
{
 int help;
 help = \*x;
 \*x = \*y;
 \*y = help;
}


void bubble(int a[],int n)
{
 int i,j;
 for (i=0; ia[j+1]) dreieckstausch(&a[j],&a[j+1]);
 }
 }
}

void merge(int a[], int low, int high, int mitte) //Zusammenfügen mit Hilfsarray c
{
 int i,j,k, b[5000];
 i=0;
 j=low;
 //erste Hälfte des Arrays a ins Hilfsarray b
 while (j


_[MOD: code-tags in pre-tags umgewandelt]_

Hallo,

Nun ist es so, dass ich immer eine Fehlermeldung erhalte:

„C Run-Time Check Failure #2 - Stack around the variable ‚f‘
was corrupted.“

An dieser Stelle solltest du deinen Debugger nach dem Stacktrace fragen. Wenn der Stack nicht allzu kaputt ist, solltest du herausfinden konnen, in welcher Funktion, von wo aus sie aufgerufen wurde etc.

Das ist mein letztes, zu sortierende Array für den Mergesort.
Wenn ich dieses auf 1000 Felder verkleinere, wie in dem Teil
davor, bekomme ich die gleiche Fehlermeldung, allerdings für
das Array ‚d‘, also das Merge-Array von der Sortierung mit
1000 Feldern.

Also muss ich in einer Mergefunktion einen stackoverflow
haben, nicht wahr? Ich finde aber meinen Fehler nicht. Um
Hilfe wäre ich sehr dankbar!

Das erste, was du tun kannst, ist das Problem zu reduzieren.

Tritt der Fehler auch auf, wenn du keine Zeiterfassung aussen drum herum programmierst, sondern direkt die Sortierroutine aufrufst?

Zweitens sind mir ein paar „magische“ Konstanten aufgefallen:

int i,j,k, b[5000];

Sowas ist eigentlich fast immer eine schlechte Idee. Wenn du Performance messen willst, solltest du nicht einfach mal 5000 Elemente auf dem Stack allokieren, ausser der Algorithmus braucht unbedingt 5000. Waere mir aber bei mergesort neu

Drittens hast du vermutlich implizite Annahmen in deinem Code, vielleicht sowas wie dass in merge(int a[], int low, int high, int mitte) die Ungleichungen
low

Hallo,
ich danke erstmal dem Mod, der den Quellcode leserlich gestaltet hat.

Ich habe nun weiter gewerkelt und einzelne Programmteile Schritt für Schritt in ein neues Programm kopiert. Dabei habe ich auch berücksichtigt, die Zeitmessung und das Erzeugen des Zufallsarrays auszusparen.

So ist mir auch der Fehler aufgefallen, bzw ein Fehler (denn nun bekomme ich keine Fehlermeldung mehr):
Den Funktionen Mergesort/Bubble werden die Längen der zu bearbeitenden Felder übergeben. Dabei habe ich die Zahl der Felder angegeben, nicht aber bedacht, dass ein Array mit der 0ten Stelle zu zählen beginnt. Also musste man alle Angaben der Arraylänge um 1 subtrahieren - schon ist der Stack nicht überfüllt.

zum Beispiel:

 printf("\n\n\nmit einem Array von **10** Feldern:\n");
 zeitB = Zeitmessung(a, &bubble[0], **9** ); 

An dieser Stelle solltest du deinen Debugger nach dem
Stacktrace fragen. Wenn der Stack nicht allzu kaputt ist,
solltest du herausfinden konnen, in welcher Funktion, von wo
aus sie aufgerufen wurde etc.

Aus Interesse:
wie komme ich in C an den Stacktrace?

Zweitens sind mir ein paar „magische“ Konstanten aufgefallen:

int i,j,k, b[5000];

i, j, k sind ja nur Zeiger, um das Array abzutasten.
b stellt ein Hilfsarray dar, mH dessen die zu sortierenden Mergeteile in die richtige Reihenfolge gebracht werden. Da b in meiner Programmierung nur halb so groß ist, wie das ursprungsarray, könnte ich es auf 2500 Felder reduzieren.
Aber noch mehr?
In meinem dritten Fall, also einer Sortierung von 5000 Zahlen, brauche ich doch ebenso viel Platz (bzw 2500 Felder) in dem Hilfsarray, oder?

Aber auf jedenfall großen Dank dir!

Streuselchen

Hallo,

ich danke erstmal dem Mod, der den Quellcode leserlich
gestaltet hat.

bitteschoen.

An dieser Stelle solltest du deinen Debugger nach dem
Stacktrace fragen. Wenn der Stack nicht allzu kaputt ist,
solltest du herausfinden konnen, in welcher Funktion, von wo
aus sie aufgerufen wurde etc.

Aus Interesse:
wie komme ich in C an den Stacktrace?

Mit dem Debugger, oder ansonsten abhaengig vom Betriebssystem.
Ich kenne mich mit Windows nicht aus, aber hier scheint es ein paar gute Links zu geben, die dir weiter helfen koennten:

http://discuss.joelonsoftware.com/default.asp?joel.3…

Zweitens sind mir ein paar „magische“ Konstanten aufgefallen:

int i,j,k, b[5000];

i, j, k sind ja nur Zeiger, um das Array abzutasten.
b stellt ein Hilfsarray dar, mH dessen die zu sortierenden
Mergeteile in die richtige Reihenfolge gebracht werden. Da b
in meiner Programmierung nur halb so groß ist, wie das
ursprungsarray, könnte ich es auf 2500 Felder reduzieren.
Aber noch mehr?
In meinem dritten Fall, also einer Sortierung von 5000 Zahlen,
brauche ich doch ebenso viel Platz (bzw 2500 Felder) in dem
Hilfsarray, oder?

Du hast ja selbst erklaert, dass die noetige Gruesse von b von der Anzahl der zu sortierenden Elemente abhaengt. Das tut es aber in deinem Programm nicht, darauf wollte ich hinaus. Wenn jemand probiert, die Routine mit 10000 Elementen aufzurufen, wird sie crashen.

Also muss die Routine die maximale Anzahl an Elementen erfahren, und dementsprechend zur Laufzeit Speicher allokieren.

Gruesse,
Moritz