new schlägt fehl



  • Hallo. Ich habe ein C-Programm, dass mir das Schallfeld eines Ultraschallsenders berechnen soll. Dabei werden alle berechneten Werte in einem Feld abgelegt. Bei ungünstiger Wahl meiner Parameter kommt es zu einem mir nicht nachvollziehbaren Fehler.

    int main(){
    	int breite_Wandler = 20;
    	int hoehe_Wandler = 10;
    	Wandler *neuerWandler = new Wandler(breite_Wandler, hoehe_Wandler, 0, 0);
    	neuerWandler->init_feld();
    	int breite_ebene = 60;
    	int hoehe_ebene = 60;
    	int abstandZumSender = 200;
    	Empfangsebene *empfaenger;
    	empfaenger = new Empfangsebene(hoehe_ebene, breite_ebene, abstandZumSender);
    	empfaenger->initFeld();
    
    	// Materialparameter:
    
    	const int c = 5920; // Schallgeschwindigkeit in m/s
    
    	empfaenger->berechneWerte(neuerWandler, c);
    	speichern(*empfaenger, breite_ebene, hoehe_ebene);
    	//	delete(neuerWandler); // Führt zum Programmabsturz
    	//	delete(empfaenger);   // Führt zum Programmabsturz
    }
    

    Führe ich das Programm aus, dann kommt die Meldung, das Programm hat einen Fehler verursacht und muss beendet werden. Beim Debuggen sagt es in Zeile 10 sayonara. Es wird (wie auch beim Wandlerobjekt) ein Feld initialisiert. Der Konstruktor sieht so aus (beim Wandler ebenfalls):

    Empfangsebene::Empfangsebene(int x, int y, int z)
    : x_ausdehnung(x), y_ausdehnung(y), z_position(z)
    {
    	feld = new double[x_ausdehnung*y_ausdehnung];
    }
    

    Setze ich ganz am Anfang breite_Wandler auf einen Wert kleiner oder gleich hoehe_Wandler, dann funktioniert das Programm. Da es am Ende aber ebenfalls zu einem Programmabsturz kommt, wenn ich die delete-Befehle auf die erzeigten Objekte anwende, so war zuvor schon meine Vermutung, dass ich hier irgendwo was ungezogenes tue. Da an diesem Punkt mein Schallfeld bereits berechnet war, hat mich das bis Dato nicht allzusehr gestört.

    Für hoehe_Wandler kann ich kurioserweise Werte eingeben, die größer als breite_Wandler sind.

    Falls wer eine Idee hat wo ich mich hier verzettelt haben könnte, wäre ich für Anregungen sehr dankbar.



  • Dann setz doch mal einen Breakpoint in den Konstruktor von Empfangsebene oder steppe von Zeile 10 aus mittels F11 mal dort hinein und schau, was passiert. Ggfs. ist vielleicht auch schon bei der Konstruktion von neuerWandler was schiefgelaufen, was nachhaltig den restlichen Programmablauf negativ beeinflusst.
    Für mehr Hilfe bräuchte man schon mehr Quellcode...



  • Also am Feld solte es nicht liegen, sond ja nur ca 28-29kb



  • Also mit dem Debugger hab ich es schon probiert. Da kommt halt bei Zeile 10 ein "Microsoft C++-Ausnahme: std::bad_alloc an Speicherposition 0x0012fdc4.."

    Wegen mehr Quellcode... da ist natürlich die Frage, was noch interessant sein sollte. Es wird ja bis zu dem Fehler noch nicht allzuviel getan. Was auf jeden Fall noch wichtig ist, ist der Konstruktor zum Wandler. Außerdem pack ich rein zur Vollständigkeit mal noch init_Feld() vom Wandlerobjekt mit hinzu.

    Konstruktor von Wandler:

    Wandler::Wandler(int x1, int y1, int x2, int y2)
    : x_ausdehnung(x1), y_ausdehnung(y1), raumKoordinateX(x2), raumKoordinateY(y2)
    {
    	feld = new bool[x_ausdehnung*y_ausdehnung];
    }
    

    initFeld() der Klasse Wandler:

    void Wandler::init_feld(){
    	for (int i = 0; i < x_ausdehnung; i++){
    		for (int j = 0; j < y_ausdehnung; j++){
    			feld[x_ausdehnung*i+j] = true;
    		}
    	}
    }
    


  • StinkePunk schrieb:

    void Wandler::init_feld(){
    	for (int i = 0; i < x_ausdehnung; i++){
    		for (int j = 0; j < y_ausdehnung; j++){
    			feld[x_ausdehnung*i+j] = true;
    		}
    	}
    }
    

    also bei i=x_ausdehnung würde feld[x_ausdehnung*i+j] zu feld[x_ausdehnung*x_ausdehnung+j], also evtl mehr als x_ausdehnung*y_ausdehnung, oder?



  • Na i wird aber nicht so groß wie x_ausdehnung, da ja da nur "<" und nicht "<=" steht. Die Initialisierung mach er auch und ich kann mir schön das Feld ausgeben lassen.



  • debug doch mal bei zeile 10 rein und schau dann wo es schief läuft. zeile 10 gibt dir sicher keine exeption. eher dann in Empfangsebene.
    wie schon geschrieben wurde da dann mit F11 rein.



  • Volkard hat aber recht. Wenn man die Indzierung selber berechnet, wäre es

    Spaltenanzahl * aktuelle Zeile + aktuelle Spalte, also

    feld[y_ausdehnung*i + j]
    

    Durch StinkePunkts falsche Adressberechnung greift er auf nicht allokierten Speicher zu, was den Fehler auslöst



  • Jo, genau das wars. Nach mühseligem Debuggen hab ich auch endlich gemerkt, warum mein Programm mich nicht versteht!



  • StinkePunk schrieb:

    ..., warum mein Programm mich nicht versteht!

    Ich glaube, dass muss anders herum lauten... 🤡


Anmelden zum Antworten