【发布时间】:2014-04-10 15:30:42
【问题描述】:
我正在编写一个使用 Boost.Asio 发送和接收图像的 C++ 程序。
编译时我没有收到错误,但在执行并发送图像时,接收图像的程序崩溃并给出以下错误消息(在 Visual Studio 2012,Windows 7 32 位中):
调试断言失败:
程序:[…]
\DataSender.exe
档案:f:\dd\vctools\crt_bld\self_x86\crt\src\dbgdel.cpp
线路:52表达式:
_BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
我将 4096 字节大小的包读取到一个指向 char 数组的指针中,同时仍有要读取的传入字节。在最后的循环中——如果要读取的字节数少于 4096——我删除指针并创建一个指向剩余字节大小的 char 数组的指针。直到这里它仍然有效。
但是当我尝试在循环结束时再次删除 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 指针数组时我做错了什么,但我还没有弄清楚。
有人能指出正确的方向吗?
【问题讨论】:
-
delete[buffer];这很好奇,你不想要delete [] buffer;吗? (只是问,我对你的说法有点困惑)。哦,顺便说一句,您在 if 语句中分配的buffer是 if 范围的本地。你在这里漏水了。 -
使用 std::vector。 1)它更安全,更容易使用,2)它可能会比你现在正在做的新/删除体操运行得更快。如果缓冲区恰好更小,使用向量调整缓冲区大小将不会通过调用 new[]/delete[] 的过程。
-
确实没有理由调整缓冲区大小以使其更小。只需跟踪接收到的数据量,然后只读出那么多数据。
-
@JBL:糟糕,这只是一个错字。在实际代码中它是
delete[] buffer。但是谢谢,我不知道如果我在循环内部或外部声明某些内容会有所不同。
标签: c++ arrays pointers boost-asio delete-operator