1

我在处理缓冲区(复制、连接等)时非常困惑,尤其是“新”或 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' 运算符。malloc、最小化访问冲突错误等)

非常感谢..:)

4

2 回答 2

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]在旧编译器中使用熟悉)。

于 2013-01-25T15:40:41.520 回答
1

看来您没有初始化 pszFullCode。如果您希望使用某个指针作为 strcat 的第一个参数,您应该事先使其指向一个合适的缓冲区。

于 2013-01-25T15:18:14.147 回答