1

私はバッファ(コピー、連結など)、特に「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' operator.malloc、アクセス違反エラーの最小化など)

どうもありがとう..:)

4

2 に答える 2

2

私はそれが尋ねられた質問にほとんど答えていると思います:

「バッファ、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 にデータを提供する必要が生じた場合でも、メソッドvectorによってメモリへの生のアクセスを取得できます (C++11 のみ。古いコンパイラで.data()は使い慣れたものを使用してください)。&Block[0]

于 2013-01-25T15:40:41.520 に答える
1

pszFullCodeを初期化していないようです。strcatの最初の引数としてポインタを使用する場合は、事前に適切なバッファを指すようにする必要があります。

于 2013-01-25T15:18:14.147 に答える