3

そのための Web サーバーとクライアントのテスト スタブを作成しています。パラメータのメモリ管理について質問があります。

クライアントから、soap 関数 ns1_func1(input * pInput, output* pOutput) を呼び出しています。これで、入力クラスと出力クラスの両方に、他の構造体へのポインターが含まれるようになりました。

例えば

クラス出力 { class abc * p1; クラス定義 * p2; };

私の質問は、メモリ割り当ての責任者は誰ですか? クライアントは入力メモリ割り当てを担当し、サーバーは出力メモリ管理を担当しますか?

現在、私のクライアントコードは次のようになっています

client_fn()
{

 ...

 input inp1;
 output * pOutput = NULL;
 ns1_func1(&inp1, pOutput);
 if(pOutput == NULL)
 {
   cout<<"pOut is NULL\n";
   return ERR;
 }
 else
 {
   // retrive output values from pOutput
 }

 ...
}

soap_new_Output(soap, -1) を使用してサーバーから pOutput を割り当てているにもかかわらず、ns1_func1 を呼び出した後、常に pOutput を NULL として取得しています。

また、soap_destroy を呼び出すと自動的に割り当て解除されるメモリを割り当てるには、soap_new_X を使用する必要があると理解しています。間違っている場合は修正してください。

基本的に、そのような場合に誰がメモリの割り当て/割り当て解除を行うべきかについての知識がなくてもがき苦しんでいます。

どんな助けでも素晴らしいでしょう。

4

4 に答える 4

1

通常、クライアントとサーバーは異なるプロセスまたは異なるマシンであるため、それぞれが独自のメモリ管理を担当します。クライアントは、入力パラメータ用にメモリを割り当てる必要があります。これは、gsoap によってシリアル化されてサーバーに送信されます。

サーバーは入力パラメータを逆シリアル化し、そのために必要なメモリを割り当てます。出力用にメモリを割り当て、gsoap がシリアライズしてクライアントに送り返します。クライアントはサーバーの応答を逆シリアル化し、そのために必要なメモリを割り当てます。

メモリ割り当てには必ず soap_malloc (et al) を使用する必要があります。これは、SOAP 呼び出しがクリーンアップされたときに解放する必要があるものを gsoap ライブラリが追跡できる唯一の方法です。

あなたが与えた特定の ns1_func1 の例では、サーバーが応答を割り当て、生成されたクライアントコードは必要なメモリを割り当てることになっています。その呼び出しの WSDL に何か問題がある可能性があります。生成されているクライアント コードが予期したものではない可能性があります。

于 2008-12-23T05:39:50.883 に答える
0

このコードを実行した後:

output * pOutput = NULL;
ns1_func1(&inp1, pOutput);

ns1_funcが何を実行しても、 pOutputは常にNULLになります。pOutputのを関数に渡します。この場合はNULLです。この関数には、pOutputのアドレス(&pOutputとして記述)がわからない限り、その値を変更する方法はありません。

ns1_func1は、「出力」構造体へのポインターを要求します。これは、そこに出力データを書き込みたいためです。つまり、スタックのいずれかにそのスペースを割り当てる必要があります。

output theOutput;
output * pOutput = &theOutput;
ns1_func1(&inp1, pOutput);

またはヒープ上:

output * pOutput = malloc(sizeof(output));
ns1_func1(&inp1, pOutput);
...
free(pOutput);

ns1_func1がメモリを割り当てる場合は、出力構造体へのポインタを返す必要があります。そのためには、そのポインタのアドレス、またはポインタへのポインタを要求する必要があります。言い換えれば、次のような宣言です。

output * pOutput = NULL;
different_ns1_func1(&inp1, &pOutput);
if (pOutput != NULL) {
    ...
    free(pOutput);
}

これが少し混乱している場合は申し訳ありませんが、ポインタからポインタへのすべての話がありますが、あなたの質問に対する基本的な答えは、関数がデータのアドレスを要求しているのではなく、関数が書き込むためのメモリを割り当てる必要があるということですデータへのポインタのアドレス

于 2009-10-27T23:07:59.263 に答える
0

ns1_func1 の署名は何ですか? ns1_func1( Input*, Output*) または ns1_func1( Input*, Output*& ) ですか? 最初のケースでは、null 以外の値を取得することはできません。

于 2009-01-05T07:05:32.330 に答える
0

デントンさん、ありがとう

私が直面している問題は、サーバーで、soap_new_abc と soap_new_def を使用してクラス abc と def にメモリを割り当てていることです。これらは、クリーンアップ中に解放されません。クリーンアップ セクションでは、soap_destroy、soap_end、soap_free を呼び出しています。gsoap のドキュメントによると、soap_free は、soap_new_X を介して割り当てられたクラスの ~tors を呼び出す必要がありますが、それは行われていません。私は実際に ctors に DEBUG ステートメントを入れ、soapC.cpp に ~tors を入れました。ctor の DEBUG ステートメントは表示されますが、~tors のステートメントは表示されません。そのため、メモリリークが発生する可能性があります。

soap_delete_X は、soap_free からのクリーンアップ中に自動的に呼び出されるはずではありませんか?

于 2008-12-28T20:51:54.423 に答える