В согласованном «Место чтения нарушения доступа» при записи в двоичный файл с использованием fstream - PullRequest
0 голосов
/ 30 июня 2011

Я пытаюсь адаптировать кусок кода, чтобы получить БПФ некоторых входных данных. Все идет хорошо, принимая преобразование. Моя проблема возникает, когда я пытаюсь записать преобразование в двоичный файл, и в этот момент я получаю:

Необработанное исключение в 0x68d0ca24 (msvcr100d.dll) в FFT.exe: 0xC0000005: Место чтения нарушения доступа 0x00161000.

Самое странное, это происходит не каждый раз, когда я компилирую и запускаю программу. Примерно каждый третий раз он работает нормально и сохраняет данные в файл.

#include <iostream>
#include <fstream>
#include <cmath>
#include <cstdlib>

#include "dft/FFT.h"
#include "ffft/FFTReal.h"

int main ()
{
    using namespace std;
    const char* dataFile = "C:/users/gad18/documents/temp/testData.dat";
    const char* transformFile = "C:/users/gad18/documents/temp/DFTtestOutput.dat";
    int length;
    off_t size;

    fstream inFile;
inFile.open( dataFile, ios_base::in | ios_base::binary );
if ( ! inFile.is_open() )
{
    cout << "Error opening " << dataFile << " for reading." << endl;
    cout << "Terminating process." << endl;
    cin.get();
    exit( EXIT_FAILURE );
}


cout << "Reading from " << dataFile << endl;
inFile.seekg( 0, ios_base::end );
size = static_cast <off_t> ( inFile.tellg() );
inFile.seekg( 0, ios_base::beg );
length = size / sizeof( float );

float* buffer = new float[ length ];
float* F = new float [length ];

inFile.read( (char*) buffer, length * sizeof( float ) );
inFile.close();

cout << size << " bytes read in." << endl;
cout << length << " float elements read into memory." << endl;

cout << "Press return key to creat DFT object..." << endl;
cin.sync();
cin.get();

cout << "Creating DFT object of length " << length << " points." << endl;

dft::FFT dft_object( length );
ffft::FFTReal<float> ffft_object( length );

int bits_out = dft_object.get_bits();
cout << "Successfully created DFT object with " << bits_out << " bit depth." << endl;

cout << "Press return key to attempt fast Fourier transform of data..." << endl;
cin.sync();
cin.get();

dft_object.compute_FFT( F, buffer );

cout << "Press return key to save transform data..." << endl;
cin.sync();
cin.get();

fstream outFile;
outFile.open( transformFile, ios_base::out | ios_base::trunc | ios_base::binary );
if ( ! outFile.is_open() )
{
    cout << "Error opening " << dataFile << " for writing." << endl;
    cout << "Terminating process." << endl;
    cin.get();
    exit( EXIT_FAILURE );
}
else
{
    outFile.write( (char*) &F, length * sizeof( float ) );
    size = outFile.tellg();
    cout << "Wrote " << size << " bytes to " << transformFile << endl;
    outFile.close();
}

delete [] buffer;
delete [] F;

cout << "Press return key to continue...";
cin.sync();
cin.get();
return 0;
} // int main()

Приношу свои извинения, если это неправильный способ включить код в вопрос (первый пост здесь).

Похоже, что исключение последовательно возникает в строке 202 streambuf (может быть, это помогает?).

Что действительно меня отталкивает, так это то, что это кажется случайным явлением, и поскольку я впервые столкнулся с этой проблемой, я не уверен, с чего начать поиск ошибки. Судя по другим сообщениям об этом исключении, может быть проблема с моим использованием указателей?

Буду очень признателен за любую помощь в решении проблемы или о том, как справиться с устранением ошибок.

Спасибо, Грег

Ответы [ 2 ]

2 голосов
/ 30 июня 2011

Я считаю, что проблема здесь: outFile.write( (char*) &F, length * sizeof( float ) );

Я думаю, что вы хотите:

    outFile.write( (char*) F, length * sizeof( float ) );

Вы дамп памяти, начиная с адреса указателя, а неадрес хранится в указателе.Если эти два адреса имеют правильные отношения в памяти, запись будет работать, хотя некоторые данные в файле будут неправильными.Но поведение непредсказуемо и может привести к сбою.

На вашем месте я бы подумал о формате файла, который был бы более надежным, чем дамп памяти, представляющий ваш выходной массив -

1 голос
/ 30 июня 2011

Поскольку вы работаете в Windows, попробуйте загрузить Application Verifier из MSDN.(Извините, набираю это из моего WP7, поэтому у меня нет удобной ссылки).При включенном pageheap и базовых проверках он может точно определить проблему.

...