16

私は Java には精通していますが、C にはあまり詳しくありません。

Java では、何かを実行して文字列を返すメソッドがある場合、次のようになります。

private String doSomething(...) {
    String s;
    // do something;
    return s;
}

C の同等の構文は機能せず、明らかに間違っています。

char* doSomething(...) {
    char s[100];
    // do something;
    return s;
}

もちろん、私はできる:

char* doSomething(...) {
    char *s;
    s = malloc(100 * sizeof(char));
    // do something;
    return s;
}

これはうまくいくでしょう(私は思います!)が、私はめったにこの方法でコードを見ません(不必要にヒープを埋めているからですか?)

最も一般的に、私は見ます:

bool doSomething(char *s) {
    // do something that copies chars to s
    return true;
}

呼び出しステートメントは次のようになります。

char s[100];
doSomething(s);

関数自体の内部まで char 配列のサイズがわからない場合はどうすればよいですか? つまり、関数の外側で char 配列を宣言してから渡すことはできません。

そのようなシナリオに対処する正しい方法は何でしょうか?

4

5 に答える 5

19

呼び出し元のコードがメモリの割り当てを担当するようにします。例 2 のバッファーとバッファーの長さを渡します。

bool doSomething(char *s, size_t buflen)
{ 
    // do something that copies chars to s up to max of buflen
    return true; 
} 

呼び出し元のコードがメモリ管理を制御しているため、これによりリークが減少する傾向があります。

于 2011-11-29T13:02:26.097 に答える
5

静的割り当ての例 (コンパイル時に最大バッファー サイズを考慮する必要があります)

buf[MAX_NO];
do(buf, MAX_NO);

_Bool do(char *s, size_t len) { 
// use len as boundary in your operations
}

または動的割り当ての場合(あなたが言ったようにmallocを使用し、ポインターを使用してバッファーの場所とサイズを保存します)

char *s = NULL;
size_t final_len;
do(&s, &final_len);

_Bool do(char** s, size_t* final_len) {
    size_t len = discoverSize();
    char* buf = (char*) malloc(sizeof(char) * len);

    *s = buf; //save memory location
    *final_len = len; //save buffer size
    // use len as boundary in your operations

}

// do whatever
free(s); //remember to free the buffer for politeness
于 2011-11-29T13:18:52.070 に答える
2

返される文字列の正しいサイズがわからない場合は、mallocソリューションを使用してください。もちろん、文字列を使いfree終わったら、文字列にする必要があります。

于 2011-11-29T13:03:44.990 に答える
1

C では配列を返すことはできません。

ポインターを返すことができるので、( C言語でのプログラミングに関する優れたを読んで) 配列とポインターの違いを学ぶ必要があります。

一般的なイディオムは、動的に割り当てられたポインターを返すことです。次に、誰がポインターを解放するかを示す規則が必要です。

配列を含む構造体を返すこともできます。

補遺

C でガベージ コレクターが必要な場合は、Boehm のガベージ コレクターを試してください。

于 2011-11-29T13:03:45.347 に答える
0

最も安全な方法は、他の人が言ったように、割り当ての責任を呼び出し元に任せることです。

ただし、再入可能コードと Java の単純さが必要ない場合、C で同等の構文を使用すると、次のようになります。

char* doSomething(...) {
    static char s[100];
    // do something;
    return s;
}
于 2011-11-29T13:11:26.137 に答える