1

私は次の機能を持っています:

char * decrypt(const char *p, int key) {
  char *tmp = malloc(strlen(p) + 1);
  for (int i = 0; p[i] != '\0'; i++) {
    if (p[i] >= 'A' && p[i] <= 'Z') {
      if (key <= p[i] - 'A')
        tmp[i] = p[i] - key;
      else
        tmp[i] = p[i] - key + 'Z' - 'A' + 1;
    } else if (p[i] >= 'a' && p[i] <= 'z') {
      if (key <= p[i] - 'a')
        tmp[i] = p[i] - key;
      else
        tmp[i] = p[i] - key + 'Z' - 'A' + 1;
    }
  }
  return tmp;
}

私は一時的なポインタ*tempにメモリを割り当てています:

char *tmp = malloc(strlen(p) + 1);

しかし、私はそれをどこにも解放していません。

私の知る限り、そのメモリを解放するには 4 つのオプションがあります。

  1. 同じスコープで使用free()します(ポインターを返さなければならないため、私には不可能です)
  2. alloca()すべてのコンパイラでサポートされていない使用(ANSI C ではない)
  3. malloc()関数の外側のポインターとそのポインターを関数に渡し、次に関数の外側に渡しfree()ます
  4. 返されたポインタを変数に割り当て、その変数を解放する

これはオプション #4 のコードです。

char *var;
var = malloc(MAX);
var = decrypt("Hello", 1);
free(var);

そのポインターは既に編集されているため、返されたポインターを割り当てるときにmalloc()変数を使用する必要がありますか?varmalloc()

私の質問は次のとおりです。

malloc()関数内で使用する最良の方法は何ですか?

4 番目のオプションを使用するmalloc()場合、返されたポインターを割り当てる前に変数を使用する必要がありますか?

4

4 に答える 4

3

そのはず:

char *var = decrypt(whatever);
// ...use var...
free(var);

コード例で事前にメモリをリークしたい理由がわかりません。

事前にメモリを割り当て、関数で埋めるという計画 (3) も実行可能ですが、関数がバッファ オーバーフローを引き起こす可能性が生じるため、より冗長なコードになります。

alloca関数が戻るときにそのスペースの割り当てが解除されるため、機能しません。

于 2015-02-22T21:16:05.913 に答える
2

decrypt関数が結果を書き込むポインタを提供するように、関数のシグネチャを変更できます。

void decrypt(char* dest, const char *p, int key);

このように、このメモリ空間を管理するのは呼び出し側の全責任です。

于 2015-02-22T21:17:33.613 に答える
0

簡単な代替方法は、文字列をその場で変更することです。

void decrypt(char *p, int key) {
    for (; *p; p++) {
        if (*p >= 'A' && *p <= 'Z') {
            if (key <= *p - 'A')
                *p -= key;
            else
                *p += ('Z' - 'A' + 1) - key;
        } else
        if (*p >= 'a' && *p <= 'z') {
            if (key <= *p - 'a')
                *p -= key;
            else
                *p += ('Z' - 'A' + 1) - key;
        }
    }
}

256 バイト配列を使用すると、はるかに単純で効率的な実装を作成できることに注意してください。

于 2015-02-22T21:40:02.480 に答える
0

Q: 関数内で malloc() を使用する最良の方法はどれですか?

A: (現在のように) 本当に関数内にメモリを割り当てたい場合は、この関数の外でメモリを解放する必要があります (おそらく他の補完的な関数を使用して)。メモリ割り当ての事実を思い出すために、そのような関数に (たとえばdecrypt_ma()の代わりに) 特別な名前を使用することがあります。decrypt()

Q: 4 番目の方法を使用する場合、返されたポインターを割り当てる前にその変数を malloc() する必要がありますか?

A: を呼び出す前にメモリを割り当てた場合decrypt()decrypt()はポインタをまったく返すべきではありません (すべての操作は、関数の本体にpあるべきではありません)。const

于 2015-02-22T21:17:46.373 に答える