在文件中写入字符数组时出现访问冲突
Access Violation when writing an char array in a file
我正在编写一个小程序来完成主程序的所有 "write in file" 工作。数据是大小不固定的结构。它们有很多,并且将来会添加新的。
因此,我决定使用 char 数组并将指向这些数组的指针从一个方法传递到另一个方法。
70% 的时间代码按预期运行,但我经常在写入数组时遇到 "access violation" 错误,有时这个错误会连续出现几次。我只是找不到模式。
请注意,Execute 在不同的线程上运行。
struct BufferElement
{
char* ptrData;
int TotalBytes;
int StartPosition;
std::string FileName;
};
class FileThread
{
private:
std::vector<BufferElement> Queue;
bool BoolThread;
std::ofstream writestream;
//This Method calls the "WriteInFile" Method for the first element in the
//Queue and erases it from the vector
void Execute( void )
{
while( BoolThread )
{
if( Queue.size() > 0 )
{
if( WriteInFile() )
{
delete[] Queue.at( 0 ).ptrData;
Queue.erase( Queue.begin() );
}
}
}
}
//This Method writes the first Element of the Queue in the file
bool WriteInFile( void )
{
if( Queue.at(0).ptrData == NULL )
{
return true;
}
writestream.open( Queue.at(0).FileName.c_str(), std::ios::in |
std::ios::out | std::ios::binary );
if( !writestream.is_open() )
{
writestream.close();
writestream.clear();
return false;
}
writestream.seekp( Queue.at( 0 ).StartPosition );
writestream.write( Queue.at( 0 ).ptrData, Queue.at( 0 ).TotalBytes );
writestream.close();
writestream.clear();
return true;
}
public:
void EndThread(void)
{
BoolThread = false;
for( int i = 0; i < Queue.size(); i++ )
{
delete[] Queue.at( i ).ptrData;
}
}
template< typename T >
void WriteOrder( std::string _FileName, T _Data, int _StartPosition )
{
BufferElement Temp_BufferElement;
Temp_BufferElement.TotalBytes = sizeof( _Data );
Temp_BufferElement.StartPosition = _StartPosition;
Temp_BufferElement.FileName = _FileName;
Temp_BufferElement.ptrData = new char[ Temp_BufferElement.TotalBytes ];
memcpy( Temp_BufferElement.DataPtr, _Data, Temp_BufferElement.TotalBytes );
Queue.push_back( Temp_BufferElement );
}
};
int main(void)
{
std::string Path = "..\Data\Test.dat";
FileThread Writer;
for( int i = 0; i < 1000; i++ )
{
char array[] = {'H','e','l','l','o',' ','W','o','r','l','d','!','[=10=]'};
Writer.WriteOrder( Path, array, i * sizeof( array );
}
system("pause");
Writer.EndThread();
return 0;
}
如果有人能看一下代码,我会很高兴。也许我只是忽略了一些东西。
我正在使用 Borland Turbo C++ Builder 并且 Thread 是来自 vcl class.
的对象
您需要同步对队列的访问。如果您的主线程在工作线程修改队列时写入队列,您可能会崩溃。此外,如果你这样做 push_back
数组内存可能会变得无效,而工作人员仍在使用该无效内存。
我也看不到 BoolThread
在哪里初始化或更改。所以要么这个例子不完整,要么它可能表现得很奇怪。
void WriteOrder( std::string _FileName, T _Data, int _StartPosition )
{
BufferElement Temp_BufferElement;
Temp_BufferElement.TotalBytes = sizeof( _Data );
Temp_BufferElement.StartPosition = _StartPosition;
Temp_BufferElement.FileName = _FileName;
Temp_BufferElement.ptrData = new char[ Temp_BufferElement.TotalBytes ];
memcpy( Temp_BufferElement.DataPtr, _Data, Temp_BufferElement.TotalBytes );
Queue.push_back( Temp_BufferElement );
}
如果这样称呼:
Writer.WriteOrder( Path, array, i * sizeof( array ));
Temp_BufferElement.TotalBytes 将容纳 4(或 8)(sizeof(_Data))似乎这不是您想要的。这一行:
Temp_BufferElement.ptrData = new char[ Temp_BufferElement.TotalBytes ];
memcpy( Temp_BufferElement.DataPtr, _Data, Temp_BufferElement.TotalBytes );
将在堆上分配并复制 4 个字节(取决于指针的大小,32/64 位程序)
此代码:
Queue.push_back( Temp_BufferElement );
如果 Queue.size() == Queue.capacity() 执行此代码之前,向量将重新分配自身,导致线程执行 "Execute" 函数出现同步问题。
我正在编写一个小程序来完成主程序的所有 "write in file" 工作。数据是大小不固定的结构。它们有很多,并且将来会添加新的。 因此,我决定使用 char 数组并将指向这些数组的指针从一个方法传递到另一个方法。
70% 的时间代码按预期运行,但我经常在写入数组时遇到 "access violation" 错误,有时这个错误会连续出现几次。我只是找不到模式。
请注意,Execute 在不同的线程上运行。
struct BufferElement
{
char* ptrData;
int TotalBytes;
int StartPosition;
std::string FileName;
};
class FileThread
{
private:
std::vector<BufferElement> Queue;
bool BoolThread;
std::ofstream writestream;
//This Method calls the "WriteInFile" Method for the first element in the
//Queue and erases it from the vector
void Execute( void )
{
while( BoolThread )
{
if( Queue.size() > 0 )
{
if( WriteInFile() )
{
delete[] Queue.at( 0 ).ptrData;
Queue.erase( Queue.begin() );
}
}
}
}
//This Method writes the first Element of the Queue in the file
bool WriteInFile( void )
{
if( Queue.at(0).ptrData == NULL )
{
return true;
}
writestream.open( Queue.at(0).FileName.c_str(), std::ios::in |
std::ios::out | std::ios::binary );
if( !writestream.is_open() )
{
writestream.close();
writestream.clear();
return false;
}
writestream.seekp( Queue.at( 0 ).StartPosition );
writestream.write( Queue.at( 0 ).ptrData, Queue.at( 0 ).TotalBytes );
writestream.close();
writestream.clear();
return true;
}
public:
void EndThread(void)
{
BoolThread = false;
for( int i = 0; i < Queue.size(); i++ )
{
delete[] Queue.at( i ).ptrData;
}
}
template< typename T >
void WriteOrder( std::string _FileName, T _Data, int _StartPosition )
{
BufferElement Temp_BufferElement;
Temp_BufferElement.TotalBytes = sizeof( _Data );
Temp_BufferElement.StartPosition = _StartPosition;
Temp_BufferElement.FileName = _FileName;
Temp_BufferElement.ptrData = new char[ Temp_BufferElement.TotalBytes ];
memcpy( Temp_BufferElement.DataPtr, _Data, Temp_BufferElement.TotalBytes );
Queue.push_back( Temp_BufferElement );
}
};
int main(void)
{
std::string Path = "..\Data\Test.dat";
FileThread Writer;
for( int i = 0; i < 1000; i++ )
{
char array[] = {'H','e','l','l','o',' ','W','o','r','l','d','!','[=10=]'};
Writer.WriteOrder( Path, array, i * sizeof( array );
}
system("pause");
Writer.EndThread();
return 0;
}
如果有人能看一下代码,我会很高兴。也许我只是忽略了一些东西。 我正在使用 Borland Turbo C++ Builder 并且 Thread 是来自 vcl class.
的对象您需要同步对队列的访问。如果您的主线程在工作线程修改队列时写入队列,您可能会崩溃。此外,如果你这样做 push_back
数组内存可能会变得无效,而工作人员仍在使用该无效内存。
我也看不到 BoolThread
在哪里初始化或更改。所以要么这个例子不完整,要么它可能表现得很奇怪。
void WriteOrder( std::string _FileName, T _Data, int _StartPosition )
{
BufferElement Temp_BufferElement;
Temp_BufferElement.TotalBytes = sizeof( _Data );
Temp_BufferElement.StartPosition = _StartPosition;
Temp_BufferElement.FileName = _FileName;
Temp_BufferElement.ptrData = new char[ Temp_BufferElement.TotalBytes ];
memcpy( Temp_BufferElement.DataPtr, _Data, Temp_BufferElement.TotalBytes );
Queue.push_back( Temp_BufferElement );
}
如果这样称呼:
Writer.WriteOrder( Path, array, i * sizeof( array ));
Temp_BufferElement.TotalBytes 将容纳 4(或 8)(sizeof(_Data))似乎这不是您想要的。这一行:
Temp_BufferElement.ptrData = new char[ Temp_BufferElement.TotalBytes ];
memcpy( Temp_BufferElement.DataPtr, _Data, Temp_BufferElement.TotalBytes );
将在堆上分配并复制 4 个字节(取决于指针的大小,32/64 位程序)
此代码:
Queue.push_back( Temp_BufferElement );
如果 Queue.size() == Queue.capacity() 执行此代码之前,向量将重新分配自身,导致线程执行 "Execute" 函数出现同步问题。