0
gcc (GCC) 4.6.3
c89
apache runtime portable libraries

こんにちは、

簡単な質問ですが、uuid値を作成しようとしています。

スタンドアロン(ブラックボックス)にする関数が欲しいので、バッファーを渡すだけで、残りは関数が実行します。

つまり、呼び出し元の関数は宣言する内容をあまり知らないため、その関数のヒープでメモリを宣言する必要があります。私はこれが悪い考えであることを知っています。なぜなら、呼び出し側はそれが終わった後にメモリを解放しなければならないからです。

これをもっとうまくやれる方法はありますか?

これを実行すると、関数が戻った後、branch_id_bufは常にnullになります。ただし、これを関数に渡したので、割り当てられたメモリを指している必要があるため、関数が戻ったときにnullにならないようにする必要があります。

アドバイスをありがとう、

static void g_get_branch_id(char *branch_id_buf);

int main(void)
{
    char *branch_id_buf = NULL;

    g_get_branch_id(branch_id_buf);

    printf("branch id [ %s ]\n", branch_id_buf);

    free(branch_id_buf);

    return 0;
}

static void g_get_branch_id(char *branch_id_buf)
{
    apr_uuid_t uuid;

#define MAGIC_COOKIE_LENGTH 9

    const char *MAGIC_COOKIE = "z9hG4bk-";
    const int BRANCH_ID_LENGTH = APR_UUID_FORMATTED_LENGTH + MAGIC_COOKIE_LENGTH;

    branch_id_buf = malloc(BRANCH_ID_LENGTH);
    if(branch_id_buf == NULL) {
        return;
    }

    strncpy(branch_id_buf, MAGIC_COOKIE, BRANCH_ID_LENGTH);
    printf("branch id [ %s ]\n", branch_id_buf);
    apr_uuid_get(&uuid);

#define PREFIX_BRANCH_LENGTH 8
    apr_uuid_format(branch_id_buf + PREFIX_BRANCH_LENGTH, &uuid);

    printf("branch id [ %s ]\n", branch_id_buf);
}
4

3 に答える 3

3

投稿されたコードでbranch_id_bufは、は関数に対してローカルです。行われた変更は呼び出し元には表示されません。

あなたは:を渡す必要がありchar**ます

char *branch_id_buf = NULL;

g_get_branch_id(&branch_id_buf);

...

void g_get_branch_id(char **branch_id_buf) {

    /* Dereference 'branch_id_buf' within this function. */
    *branch_id_buf = malloc(BRANCH_ID_LENGTH);

編集:

larsmansがコメントしているようにchar*、引数を受け入れるのではなく、返すことを検討してください。

char *branch_id_buf = g_get_branch_id();

char* g_get_branch_id() {

    char* branch_id_buf = malloc(BRANCH_ID_LENGTH);
    ...
    return branch_id_buf;
}
于 2012-04-04T09:24:31.040 に答える
2

悪い考えではありません。注意して、そのメモリを解放することを忘れないでください。それをさらに安全にするための一般的な手法はほとんどありません。参照カウントやリリースプールのようなものです。

または、「ブラックボックス」を2回呼び出すこともできます。最初に呼び出して必要なメモリ量を作成し、次に割り当て済みのバッファへのポインタを使用して2番目に呼び出します。

于 2012-04-04T09:29:24.710 に答える
1

一般に、あるモジュールに割り当てて別のモジュールに解放することは非常に悪い考えです。これはまさに、プログラムで多数のメモリリークを作成する方法です。呼び出し元に解放を任せるだけでなく、ポインターをNULLに初期化する責任もあるため、コードは特に問題があります。

そうは言っても、コンパイル時定数(?)しか扱っていないようですので、なぜmallocが必要なのかわかりません。こんな風にできないの?

static const char MAGIC_COOKIE[] = "z9hG4bk-";

#define MAGIC_COOKIE_LENGTH (sizeof(MAGIC_COOKIE)/sizeof(char))

#define BRANCH_ID_LENGTH (APR_UUID_FORMATTED_LENGTH + MAGIC_COOKIE_LENGTH)


static void g_get_branch_id (char branch_id_buf [BRANCH_ID_LENGTH]);

プロトタイプの配列の長さは、呼び出し元に、その長さのバッファーへのポインターを渡す必要があることを示しています。

于 2012-04-04T09:49:23.917 に答える