Zugriffsverletzung bei Array



  • Ich habe ein 1D Array das ich als 2D Array benutze.

    pInput = new CComplex[PlotDataSize.x*PlotDataSize.y];
    	pOutput = new CComplex[PlotDataSize.x*PlotDataSize.y];
    	pInput = Beam.GetArray();
    	Plot.SetPlotDataAmplitude(pInput);	
    	Plot.UpdatePlot();
    

    soweit klappt alles

    pInput bekommt die Daten aus

    CComplex* Laserbeam::GetArray()
    {
    	return m_Array;
    }
    

    die an Plot weitergerecht werden via

    void CGraphCtrl::SetPlotDataAmplitude(CComplex* InputArray)
    {	
    	// Get modulo faktor
    	CRect rc_dest=GetSize();
    	int div = (int)PixelNumber.x/(rc_dest.Width()+1);
    	if (div <= 1) { div=1; }
    
    	if  ((PixelNumber.x>0) && (PixelNumber.y > 0))
    	{
    		for (int ix=0; ix < PixelNumber.x; ix=ix+div)
    		{
    			for (int iy=0; iy < PixelNumber.y; iy=iy+div)
    			{			
    				pPlotData[ArrPos(ix,iy)] = GetColor(InputArray[ArrPos(ix,iy)].amplitude());
    			}
    		}
    	}
    }
    

    und dann auch auf dem Bildschirm angezeigt werden.
    Die Übergabe des Arrays scheint also zu funktionieren und es enthält auch Daten.

    Wenn ich dann jedoch später den folgenden Aufruf mache

    void CFlickerFreeDemoDlg::OnBnClickedButton1()
    {
    		FFTW.FFT2D(pInput, pOutput);
    ...
    

    dann fliegt das Programm mit

    Unbehandelte Ausnahme bei 0x00416dcb in FlickerFreeDemo.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x010a0040.

    raus an der Stelle wo an dummy übergeben wird:

    void CFFTW::FFT2D(CComplex* InArray, CComplex* OutArray)
    {		
    	if (m_Init != true)
    		return;	
    
    	for (int ix=0; ix < m_size.x; ix++)
    	{
    		for (int iy=0; iy < m_size.y; iy++)
    		{
    			double dummy = InArray[ArrPos(ix,iy)].re;
    			in[ArrPos(ix,iy)][0] = InArray[ArrPos(ix,iy)].re;
    			in[ArrPos(ix,iy)][1] = InArray[ArrPos(ix,iy)].im;			
    		}
    	}	
    ...
    

    was mache ich anders so dass es hier nicht mehr funktioniert ?

    Matthias



  • Genau dasselbe ist es nicht. Für div != 1 gibt es schon eine andere Schrittweite, so dass nicht exakt dieselbe Menge (ix, iy) angesprochen wird. Da ArrPos(ix,iy) die Adresse liefert, ist es wohl am besten, sich die letzten Werte vor dem Crash anzusehen und zu prüfen, mit welchen Werten der Adressbereich von InArray überschritten wird.



  • UBr schrieb:

    Genau dasselbe ist es nicht. Für div != 1 gibt es schon eine andere Schrittweite, so dass nicht exakt dieselbe Menge (ix, iy) angesprochen wird. Da ArrPos(ix,iy) die Adresse liefert, ist es wohl am besten, sich die letzten Werte vor dem Crash anzusehen und zu prüfen, mit welchen Werten der Adressbereich von InArray überschritten wird.

    div ist in dem Beispiel gleich 1 und der Fehler tritt bei (0,0), also dem allerersten aufruf innerhalb der Funktion auf. Ein Wertebereichsfehler sollte daher nicht das eigentliche Problem sein.

    Matthias



  • Die Frage ist dann, welchen Wert ArrPos(0, 0)hat, besonders im Vergleich zur Größe des Feldes InArray - nur als nächste Vermutung.



  • UBr schrieb:

    Die Frage ist dann, welchen Wert ArrPos(0, 0)hat, besonders im Vergleich zur Größe des Feldes InArray - nur als nächste Vermutung.

    void CFFTW::ArrPos(const int x, const int y)
    {
       return y + m_size.y * x;
    }
    

    im Falle von x=y=0 also 0

    Matthias



  • pospiech schrieb:

    Ich habe ein 1D Array das ich als 2D Array benutze.

    pInput = new CComplex[PlotDataSize.x*PlotDataSize.y];
    	pOutput = new CComplex[PlotDataSize.x*PlotDataSize.y];
    	pInput = Beam.GetArray();
    	Plot.SetPlotDataAmplitude(pInput);	
    	Plot.UpdatePlot();
    

    soweit klappt alles

    Nö, hier ist schon ein Problem. pInput "bekommt" keine Daten aus GetArray, du biegst nur den Zeiger um. Durch die Zuweisung des Rückgabewerts von GetArray an pInput ist der Speicher, den du zwei Zeilen darüber angefordert hast, verloren, weil nichts mehr darauf zeigt. Ein klassisches Speicherleck. In der Folge geht's dann wohl in die Hose, weil das, auf das pInput zeigt, nicht so groß ist, wie du glaubst.



  • Ich habe es jetzt über ein memcpy gelöst

    Beam.GetArray(pInput);	
    
    void Laserbeam::GetArray(CComplex* OutputArray)
    {
    	memcpy(OutputArray,m_Array,m_size.x*m_size.y*sizeof(CComplex));
    }
    

    Matthias



  • Saletti zäme, ond grüezi wohl frau sternimaa...

    ok, ich hab diesen zugriffsfehler auch. nur mein problem ist zusätzlich noch, das ich nix davon gecoded habe sondern es nur builden muss...darum ist es doppelt so müehsam. and that's the piont when you came on the plan!
    ich kenn mich mit dem Visual C++ 2005 Express noch nicht so aus...ich weiss nur, das man ergendwie das programm auch im speicher verfolgen kann wenn man am debuggen ist. weiss jemand wie das geht...an sonsten könnt ihr mir auch direkt helfen wenn ihr wirklich nichts besseres zu tun habt! 😉

    hier spuckt er den fehler aus:

    #ifndef WITHOUT_LOG4
          if(mLogServ==0) {
             char *logFileName = getenv(LOG_FILE);
             if(logFileName==NULL) {
                logFileName=NX_LOG_FILE_NAME;
             }
             log4::File logFile(logFileName);  //<--  Hier kommt der zugriffsfehler!
             log4::PropertyConf::configureAndWatch(logFile, 3000);
             mLogServ = new LogServ();
          }
          log = new Log4();
    

    hier noch der konstruktor von "File" im header file:

    class LOG4CXX_EXPORT File
                    {
                    public:
                        File();
                        File(const std::string& name);
    

    fehlermeldung:
    Unbehandelte Ausnahme bei 0x760823a6 in terminalCOMP.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0xcccccccc.

    falls einer ne idee hat wär ich froh...sont tüftle ich weiter...


Anmelden zum Antworten