1

const char* を返す必要がある関数があります (他の関数のホスト全体がそれを使用することになります)。

次のように定義されたものがある場合、私はそれを知っています:

const char* Foo(int n)
{
    // Some code
    .
    .
    .
    return "string literal, say";
}

それなら問題ありません。ただし、Foo が実行時にのみ決定できる文字列を返さなければならない場合 (パラメータ n に応じて ([0, 2^31-1] 内の任意の値を取る各 n は、返される文字列を一意に決定する) と言うのは正しいですか? )) 次に、ヒープを使用する必要があります (または、内部でヒープを使用する std::string のようなオブジェクトを返します)?

std::string は、私が達成したいことに対して重すぎるようです (少なくとも 2 つの関数がパーセルを渡す必要があります)。また、呼び出し元によって解放されるように Foo 内にメモリを割り当てることは、安全な方法とは思えません。この関数を必要とするオブジェクトへの参照を (簡単に) 渡すことはできません。

まだ考えていない単純なことはありますか?

編集

答えてくれてありがとう、私は std::string に行きます(私は、いくつかの char[] の内容を文字列リテラルを格納するのと同じ場所)。「重い」(そして、それらをコピーするのが思ったほど無駄ではないことに驚いています)に関しては、それは最良の言い方ではありませんでしたが、おそらく「異なる」は私の最初の不安に近かったでしょう。

4

5 に答える 5

2

関数がn 個のコンパイル時に既知の文字列のいずれかを選択することを意味する場合は、それらのいずれかに const char * を返すことができます。文字列リテラルは、C および C++ では静的な保存期間を持ちます。つまり、それらはプログラムの存続期間中存在します。したがって、ポインターを 1 つに戻すことは安全です。

const char* choose_string(int n)
{
  switch(n % 4)
  {
    case 0: return "zero";
    case 1: return "one";
    case 2: return "two";
    case 3: return "three";
  }
}

関数が実行時に文字列を動的に生成する場合は、 を渡し(char *buf, int buf_length)て結果を書き込むか、 を返す必要がありstd::stringます。

于 2013-08-27T23:50:49.930 に答える
1

を使用std::stringしますが、本当に必要な場合は... C プログラミングで使用される一般的なパターンは、最終結果のサイズを返し、バッファーを割り当て、関数を 2 回呼び出すことです。(Cスタイルで申し訳ありません。Cソリューションが必要です。Cソリューションを提供します:P)

size_t Foo(int n, char* buff, size_t buffSize)
{
  if (buff)
  {
    // check if buffSize is large enough if so fill
  }
  // calculate final string size and return
  return stringSize;
}

size_t size = Foo(x, NULL, 0); // find the size of the result
char* string = malloc(size); // allocate
Foo(x,string, size); // fill the buffer
于 2013-08-27T21:35:50.750 に答える
1

最も簡単な解決策は、std::string.

std::string を回避したい場合、代替手段の 1 つは、呼び出し元がchar[]関数にバッファーを渡すようにすることです。上限が静的にわかっている場合を除き、必要なバッファーの大きさを呼び出し元に伝えることができる関数を提供することもできます。

于 2013-08-27T21:34:41.220 に答える
0

(アスベストスーツ着用)

メモリをリークすることを検討してください。

const char* Foo(int n)
{
  static std::unordered_map<int, const char*> cache;
  if (!cache[n])
  {
    // Generate cache[n]
  }
  return cache[n];
}

うん、これはメモリリークします。最大 2^32 個の文字列に相当します。しかし、実際の文字列リテラルがあれば、常に2 ^32 文字列すべてがメモリにあることになります (そして明らかに 64 ビットのビルドが必要です - \0 だけで 4GB かかります!)

于 2013-08-27T23:01:07.447 に答える