2016-08-17 16 views
1

私はFORTRANでこのC関数から返されたCポインタをFortranに解放しますか?

char * string_val (ARGS) 
{ 
char * svalue = cJSON_GetObjectItem(nml,var_name)->valuestring; 
return svalue; 
} 

のように見えるCでのchar *のポインタを返す関数を持って、私は(ISO_C_BINDINGを使用した)Cのポインタにこれを割り当てる

​​

この部分は素晴らしい作品。 string_val関数は多く呼び出され、メモリリークの原因になっていると思います。私はsvalueポインタのメモリを解放しようとしていますが、私はsegフォールトとメモリダンプを実行しました。

void c_mem_free (void** addrOfptr) 
{ 
    free(*addrOfptr); /* free the memory pointed to */ 
    *addrOfptr=NULL;  /* Nullify the pointer ;) */ 
} 

 subroutine c_mem_free (cptr) bind(C,name="c_mem_free") 
     use iso_c_binding 
     type (c_ptr) :: cptr !< The C pointer whose memory needs to be freed 
    end subroutine 
... 
call c_mem_free(C_String_ptr) 

フリーライン上の問題へのトレースバックポイント:私は現在、このようなものを持っています。私はまた、変化するcptrを値に渡そうとしました。 type (c_ptr),VALUE :: cptr そしてvoid*addrOfptrfree(addrOfptr)をC側に持っていましたが、どちらもうまくいかないようでした。私はまた、Fortran側でsvalueのメモリ位置を見つけることに失敗しました。私は

write (6,'(z)')loc(C_String_ptr) write (6,'(z)')loc(c_loc(C_String_ptr))

のようなものを使用している場合は、これらのいずれも私がsvalueのメモリの場所をprintfのときと同じ値を与えます。 ポインタsvalueがFortranで返された後、ポインタsvalueのメモリを解放するにはどうすればよいですか? Fortranでsvalueメモリの場所を取得するにはどうすればよいですか?

+3

プログラムがC言語で完全に書かれている場合、cJSONはどのメモリを解放するためのメカニズムを提供していますか?あなたが明示的なmallocを持っていないことを考慮すると、cJSONによって割り当てられたメモリのせいで、メモリリークが発生していると思いますか?これが当てはまる場合、私はあなたの 'c_mem_free'もcJSONが提供するどんなメカニズムも使うべきだと思います。1つのトラブルシューティングの手順は、ループ内にそのようなcJSON割り当てを持つ小さなプログラムを作成し、最初にCでプログラム全体を、次にC + Fortranでメモリリークを実証しようとします。 –

+0

jsonタグが追加されるべきだと思います。どちらが分からないので、私はそれをやろうとはしません。 –

+0

@ DouglasB.Staple 'for(a = 1; a <1000000; a = a + 1){ cJSON * nml = getnml(my_json_string、nml_name、var_name); svalue = cJSON_GetObjectItem(nml、var_name) - > valuestring; //文字列値を見つけます 空き(nml); 無料(svalue); if(a%10000 == 0){printf( "a/n");} ' これはリークを発生させません。メモリはほぼ同じです。自由(svalue)がなければ、使用されているメモリは上がります。 cJSONには無料だけを使用するcJSON_freeがあります。 – byrdman1982

答えて

1

親指のルールとして、コードの外側に割り当てられたメモリを「解放」しないでください。 これはcJSONにも当てはまります。

あなたがオブジェクトを解析すると、ツリーがメモリ上に構築し、あなたが目的を達成することができ、その値は、それを変更している、など

あなたのファイルの処理を終了したら、呼び出しメモリを解放することができますcJSON_Delete(ルート);

このルーチンはあなたのためにすべてを処理します。

オブジェクト/ノードを使用して解放する場合は、cJSON_Delete(node)も使用できます。 このルーチンは「再帰的」であることを覚えておいてください。

/* Delete a cJSON structure. */ 
void cJSON_Delete(cJSON *c) 
{ 
    cJSON *next; 
    while (c) 
    { 
     next=c->next; 
     if (!(c->type&cJSON_IsReference) && c->child) cJSON_Delete(c->child); 
     if (!(c->type&cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring); 
     if (!(c->type&cJSON_StringIsConst) && c->string) cJSON_free(c->string); 
     cJSON_free(c); 
     c=next; 
    } 
} 

cJSON_Deleteが世話をするよう、cJSON_Freeを使用しないでください:あなたはノードを解放する場合は、ここでのコードで見ることができるように、それは、あまりにもすべての子供や兄弟を解放します構造体自体を解放する前にcJSON_freeを構造体の内部要素に適用する必要があります。そうしないと、メモリリークが発生します。

+0

cJSON_Deleteを使用して二倍と整数の私の関数で動作しますが、文字列関数で使用すると、文字列がポインタとして渡されるので空の文字列で終わります。 – byrdman1982

+1

@ byrdman1982、これはポインタなので、これは予想される動作です。文字列をJSON構造体から読み込んだ後に文字列を保持する必要がある場合は、文字列にコピーする必要があります。私が尋ねる質問は、なぜすぐに解散する必要があるのか​​ということです。定義上、メモリリークは、スコープから外れるポインタなどのために割り当てられたメモリがアクセス不能になるようなコードの問題です。これを行うcJSONは本当ですか? – Jauch

+0

あなたはメモリリークがあると思いますか? – Jauch

関連する問題