尝试释放字符数组的指针时出错:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
Error when trying to deallocate pointer of char array: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
我正在编写一个使用 Boost.Asio 发送和接收图像的C++程序。
编译时我没有收到错误,但是在执行并发送图像时,接收图像的程序崩溃,并显示以下错误消息(在Visual Studio 2012中,Windows 7 32位(:
调试断言失败:
程序: [...]
DataSender.exe
文件:f:ddvctoolscrt_bldself_x86crtsrcdbgdel.cpp
行:52
表达式:
_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
我将 4096 字节大小的包读入指向 char 数组的指针中,同时仍有传入字节要读取。在最后一个循环中(如果要读取的字节少于 4096 个(,我将删除指针并创建一个指向剩余字节大小的字符数组的指针。直到这里它仍然有效。
但是当我尝试在循环结束时再次删除 char 指针数组时(以便为下一个传入图像创建一个标准大小为 4096 的新 char 指针数组(,程序崩溃了。
这是我的代码摘录:
char* buffer = new char[4096];
[...]
int remainingBytes = imageSize;
[...]
// read data
while( remainingBytes > 0 )
{
boost::system::error_code error;
// use smaller buffer if remaining bytes don't fill the tcp package
// fully
if( remainingBytes < 4096 )
{
delete[] buffer; // this one doesn't give an error
bufferSize = remainingBytes;
char* buffer = new char[bufferSize];
}
// read from socket into buffer
size_t receivedBytes = socket.read_some(
boost::asio::buffer(buffer, bufferSize), error);
remainingBytes -= receivedBytes;
// count total length
totalReceivedBytes += receivedBytes;
// add current buffer to totalBuffer
for( int i = 0; i < bufferSize; i++)
{
totalBuffer.push_back(buffer[i]);
}
// if smaller buffer has been used delete it and
// create usual tcp buffer again
if( receivedBytes < 4096 )
{
delete[] buffer; // here the error occurs
bufferSize = 4096;
char* buffer = new char[bufferSize];
}
}
我也在 Debian GNU/Linux 7.2 64 位机器上运行了相同的代码,它在代码中的相同位置返回了以下错误:
*** glibc detected *** ./datasender: double free or corruption (!prev): 0x0000000002503970 ***
我假设我在解除分配 char 指针数组时做错了什么,但我还没有弄清楚。
有人可以指出我正确的方向吗?
当remainingBytes
和receivedBytes
小于 4096 时,您实际上删除了两倍的缓冲区。
实际上,您删除buffer
一次,然后将内存分配给本地buffer
,而不是外部。
然后,当您删除第二个 if 块中的buffer
时,您将再次删除相同的缓冲区。在 if 作用域中进行的分配是内存泄漏。这些变量不同。
当你这样做时
char* buffer = new char[bufferSize];
在 If 作用域中,你正在创建一个新变量,而不是将内存分配到外部buffer
变量中。因此,您正在泄漏,并且没有将内存分配到刚刚删除的缓冲区中。
无需进一步查看,您应该删除两个 if 块中buffer
前面的char*
,然后继续调试。
我会改用std::vector:
#include <vector>
//...
std::vector<char> buffer(remainingBytes);
bufferSize = remainingBytes;
//...
while( remainingBytes > 0 )
{
boost::system::error_code error;
// use smaller buffer if remaining bytes don't fill the tcp package
// fully
if( remainingBytes < 4096 )
{
buffer.resize(remainingBytes);
bufferSize = remainingBytes;
}
// read from socket into buffer
size_t receivedBytes = socket.read_some(
boost::asio::buffer(&buffer[0], bufferSize), error);
remainingBytes -= receivedBytes;
// count total length
totalReceivedBytes += receivedBytes;
// add current buffer to totalBuffer
totalBuffer.insert(totalBuffer.end(), buffer.begin(),
buffer.begin() + receivedBytes);
// if smaller buffer has been used delete it and
// create usual tcp buffer again
if( receivedBytes < 4096 )
{
buffer.resize(4096);
bufferSize = 4096;
}
}
不会有内存泄漏。
另外,我认为您的代码有一个错误,因为您应该只复制接收的字节数(read_some(( 函数的返回值(。 相反,您假定返回了缓冲区大小字符。
- what(): basic_string::_M_construct null not valid
- 无法创建 DLL:获取 DLL "is not a valid Win32 application"
- C++ DLL 运行时错误"abc.dll is not a valid WIN32 application" 。请帮助解决这个问题
- 我的代码应该接受一个数字,并返回字母等级或"Grade is not valid"但 else 语句不起作用
- "[ptr, ptr+len) must be a valid range"是什么意思?
- 在 Qt 中选择查询返回"value: not positioned on a valid record"
- C++:关于"valid pointers and references"的澄清
- 在函数中删除第一个元素后,如何更新链接列表的phead
- Is std::initializer_list{x, y, z} (CTAD) valid?
- 在 Unity 中使用 x64 c++ dll 可以"Is not a valid Win32 application error"
- 调试断言失败 BLOCK_TYPE_IS_VALID (pHead->nblockuse) 从解构函数
- 调用AAssetManager_fromJava时崩溃:"JNI WARNING: instance fieldID 0x571819bc not valid"
- _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) "return 0"后
- openCV basic_string::_S_construct null not valid
- std::shared_ptr _BLOCK_TYPE_IS_VALID(pHead->nBlockUse) 更改指针时
- 卤化物表达式:_pFirstBlock == pHead 在简单程序上崩溃
- 什么是'valid' std::function?
- BLOCK_TYPE_IS_VALID(pHead->nBlockUse) 发生在主返回
- BLOCK_TYPE_IS_VALID(pHead -> nBlockUse) 错误
- 调试断言失败!表达式:_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)