我在处理缓冲区(复制,连接等)方面非常困惑,尤其是'new'或malloc的使用。我可以正确编码而无需编译错误,但在运行时会出现问题。我得到运行时错误,如访问冲突,断言失败等。
例如,我从MSDN获得了winhttp api演示的源代码。在该代码中,他们使用while循环从服务器查询数据,直到收到所有数据。在控制台上打印每个查询数据后。
但是我希望它能够将每次接收的数据存储(附加)到新变量中,最后在控制台上打印整个数据。在dll
的情况下它也会有所帮助代码本身提供了更多详细信息。
#include <Windows.h>
#include <iostream>
#include <winhttp.h>
#pragma comment(lib,"winhttp")
using namespace std;
int strcat_b(LPTSTR &dest, LPTSTR &src, int size);
int main()
{
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
LPSTR pszOutBuffer;
LPTSTR pszFullCode;
HINTERNET hSession = NULL,
hConnect = NULL,
hRequest = NULL;
hSession = WinHttpOpen( L"Test WinHttp", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
hConnect = WinHttpConnect( hSession, L"google.com", INTERNET_DEFAULT_HTTP_PORT, 0);
hRequest = WinHttpOpenRequest( hConnect, L"GET", 0, 0, 0, 0 ,0);
WinHttpSendRequest( hRequest, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
WinHttpReceiveResponse( hRequest, NULL);
do
{
dwSize = 0;
WinHttpQueryDataAvailable( hRequest, &dwSize);
pszOutBuffer = new char[dwSize+1];
ZeroMemory(pszOutBuffer, dwSize+1);
WinHttpReadData( hRequest, (LPVOID)pszOutBuffer, dwSize, &dwDownloaded);
// Actual code here was :
printf("%s", pszOutBuffer);
// I want to append pszOutBuffer into pszFullCode..
// So I tried something like strcat(pszFullCode, pszOutBuffer)
// And finally, when while loop ends, pszFullCode will be printed or Copied into another variable.
// But I get "Access Violation error" at runtime.
delete [] pszOutBuffer;
} while (dwSize > 0);
// Here it should be able print final result: printf("%s", pszFullCode);
// In case of Dll, It should be able to copy data from pszFullCode to required Pointer.
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);
cin.get();
return 0;
}
任何人都可以提供一些链接来了解这样的概念吗? (处理缓冲区,'new'运算符.mamococ,最小化访问冲突错误等)
非常感谢.. :))
答案 0 :(得分:2)
我认为这几乎回答了问题:
如果要处理“缓冲区,新运算符,malloc,最小化访问冲突错误”,您应该学会使用标准C ++库。它充满了有用的东西,将承担管理你的记忆的负担。
例如,考虑contiguos内存块。它可以表示为:
std::vector<unsigned char> Block;
它的大小(可由Block.size()
读取)现在为0.要为它分配内存,我们可以写:
Block.reserve(size);
您也可以直接在构造函数中执行此操作:
std::vector<unsigned char> Block (size, 0); // fill it with zeros
现在,如果你想将它与另一个块连接起来,它就像:
一样简单std::vector<unsigned char> Block2;
Block.insert( Block.end(), Block2.begin(), Block2.end() );
或
std::copy(Block2.begin(), Block2.end(), std::back_inserter(Block));
所有内容都将正确重新分配,您不会遇到任何运行时错误。但是,如果你需要向设计糟糕的API或用C编写的API提供数据,你仍然可以通过vector
方法获得.data()
内存的原始访问权限(仅限C ++ 11;使用在较旧的编译器中熟悉&Block[0]
。
答案 1 :(得分:1)
您似乎没有初始化pszFullCode。如果你想使用一些指针作为strcat的第一个参数,你应该先指出一个合适的缓冲区。