2011-01-06 4 views
1

私はmallocで作成された動的メモリオブジェクトのサイズを増やす関数を書いています。この関数は、引き数として、増やすメモリブロックへのポインタ、ブロックの現在のサイズ、およびブロックを増やす量を取る必要があります。このようなCを使用して同じ関数内の異なる種類の型のサイズを取得する方法は?

何か:

int getMoreSpace(void **pnt, int size, int add) { 
    xxxxxx *tmp; /* a pointer to the same as pnt */ 
    if (tmp = realloc(pnt, (size+add)*sizeof(xxxxxx))) { /* get size of what pnt points to */ 
     *pnt=tmp; 
     return 1; 
    else return 0; 
} 

問題は、私は関数がどんなPNTポイントに作業しないようにしたいということです。どのように達成するのですか?

答えて

9

pntがローカルであり、関数が戻るとすぐに新しいポインタが失われるため、このタイプの関数は機能しない可能性があります。ポインターを更新できるように、タイプxxxxxx **の引数を取ることができますが、1つのタイプだけをサポートしているだけです。

実際の問題は、reallocの不要で有害なラッパーを作成していることです。 reallocをそのまま使用するようにしてください。それをラッピングすることによって、それをより簡単に、またはより効率的にする方法はありません。できるだけシンプルになっています。

+0

私はあなたが言っていることを実際には得られません。 pntがローカルであることはなぜ重要なのでしょうか?私は関数が返るまでそれを必要とします。 また、このラッパーはなぜ危険ですか?私はこの種のサイズ増分をプログラムの中でさまざまな状況下でやっているのですが、この機能が私のコーダーをよりクリーンでシンプルにしてくれるのは、同じことを何度も入力する必要がないからです。とにかく機能の?)。 – paldepind

+0

私は100%確信していませんが、私はC言語で 'ローカル'ポインタのようなものはないと思っています。 –

+4

@Stefanos:関数の引数は、関数が返ったときに範囲外に出るという意味で "ローカル変数" 。 'ptr'に新しい値を代入しても効果はありません。実際、コンパイラは割り当てを最適化でき、最適化する必要があります。 –

2

あなたは引数としてサイズを渡します。あなたはそれがあなたの関数と同じように見えるようにする便利なマクロを使用することができます。

#define getMoreSpace(P, SZ, ADD) getMoreSpaceFunc(&(P), sizeof(*(P)), (SZ), (ADD)) 

int getMoreSpace(void **pnt, size_t elem_size, int size, int add) { 
    *pnt = ... 
} 

編集を便利にマクロも参照による呼び出しのセマンティクスを追加する必要がありますことを示します。別のパラメータとしての要素のサイズは

+0

なぜマクロを使用していますか? sizeofは変数を渡すだけで動作しますか?私は引数として型を受け入れただけですが? – paldepind

+0

'sizeof'は演算子です。タイプを見ることができる必要があります。マクロは、変数の型が表示される元のコードのテキストに置き換えられます。あなたの関数の中では、型情報は失われますが、マクロはあなたのためにサイズで渡されます。さらに、(私が編集で説明したように)マクロを使用して、ターゲットポインタのアドレスを取得することができます。 –

+0

...また、私はあなたがこれを行うべきではないと思ってRの答えに投票しましたが、私はあなたの質問に対する技術的な答えも同様に啓発されると思っていました。 –

1

パス:

int getMoreSpace(void **pnt, int size, int add, size_t eltSize) 
{  
    void *tmp; 
    if (tmp = realloc(pnt, (size+add)*eltSize)) 
    { 
    *pnt=tmp; 
    return 1; 
    } 
    else 
    return 0; 
} 
... 

int *p = malloc(100 * sizeof *p); 
... 
if (!getMoreSpace(&p, 100, 20, sizeof *p)) 
{ 
    // panic 
} 

これは、最も簡単な解決策はないに最もエレガントなのです。 Cは動的な型情報に役立たない。

編集

はスティーブのコメントに反応して pntの種類を変更しました。

cafが指摘しているように、スティーブの「修正」でさえ、これはうまくいきません。 R.の権利;これをしないでください。

+0

これはポインタへのポインタを使わなければ動作しません。* pにはreallocが返す値は決して割り当てられません。 –

+0

@ Steve Melvin。ダー。私はそれを知っていた。本当に。私はそれを修正するために例を編集します。うわー、1日で2つのdownvotes;それは私のための記録です。 –

+0

'void *'型の左辺値を使用して 'int *'型のオブジェクトを変更することはできません。そのようなコードは未定義の動作をしています。 – caf

関連する問題