【问题标题】:Concatenate buffer with another buffer [closed]将缓冲区与另一个缓冲区连接起来[关闭]
【发布时间】:2013-01-25 15:09:35
【问题描述】:

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

非常感谢..:)

【问题讨论】:

    标签: c++ pointers memory buffer


    【解决方案1】:

    我认为这几乎可以回答所提出的问题:

    如果你想处理“缓冲区、new operator、malloc、最小化访问冲突错误”,你应该学会使用标准C++库。它充满了有用的东西,可以负担你管理记忆的负担。

    例如,考虑连续的内存块。可以表示为:

    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 提供数据,您仍然可以通过 .data() 方法获得对 vectors 内存的原始访问权(仅限 C++11;使用熟悉的 &amp;Block[0]在较旧的编译器中)。

    【讨论】:

    • 您可能应该提供一个更完整的示例,说明在访问向量之前在向量中保留内存。
    • 谢谢..我会了解的..
    • 请记住,采用大小的构造函数 resized 向量(设置其大小,如果需要,分配内存),这与 reserve 不同(设置其容量但不是它的大小)。
    【解决方案2】:

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

    【讨论】:

    • 我尝试初始化为 pszFullCode = new char;但又出错了。
    • 这样会更好:pszFullCode=new char[dwSize+1];
    • 你能在给定的代码中显示它吗? (实际上,我已经尝试了您的所有建议,但没有找到解决方案。)因为,我想在每个循环中附加数据。如果我使用 pszFullCode=new char[dwSize+1] 进行初始化;在每个循环中,则不会追加。
    • 如果你知道最大迭代次数(我们称这个数字为maxIterations),然后分配dwSize * maxIterations字节的缓冲区。否则,在每次迭代中,您需要分配一个更大的缓冲区,复制旧内容,然后调用 strcat.请注意,std::string 能够自动进行重新分配。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多