2012-02-27 18 views
2

私はまだC言語ではあまりよくないので、いくつか質問があります。 、私は2D配列内の単一の行を検索するシステムを作成したい今Cで2次元配列を持つ構造体

cache make_cache(int s, int E) { 
    int i; 
    cache new = malloc(sizeof(struct cache_handler)); 
    new->hit = 0; 
    new->miss = 0; 
    new->evict = 0; 
    line **new_line = malloc((1 << s) * sizeof(*new_line)); 
    for(i = 0; i < (1 << s); i++) 
    new_line[i] = malloc(E * sizeof(struct line_elems)); 

    new->lines = new_line; 
    return new; 
} 

typedef struct line_elems line; 
typedef struct cache_handler *cache; 

struct line_elems { // we don't care about valid/block bits in our simulator 
    int tag; 
    int freq; // for LRU principle 
}; 

struct cache_handler { 
    int hit; 
    int miss; 
    int evict; 
    line **lines; // 2d array for sets 
}; 

ではでキャッシュを初期化:私は、次の構造体のうちの2つを持っている

int search_lines(line *lines, int E, int tag, int frequency) { 
    int i; 
    for(i = 0; i < E; i++) { 
    //continue here 
    } 
} 

私はちょっと私のsearch_lines functioに入力するはずですn。 私が入力した場合:search_lines(cache->lines[0], E=5, tag=5, frequency=5)それは私が期待していることをするでしょうか?つまり、2次元配列の1行で検索しますか? cache->lines[0](line*)と同じではないと感じています。 cache->linescache->lines[0]の違いは何ですか? ->オペレータは暗黙的に1レベルの逆参照を実行するので、これは私を混乱させるでしょうか?

ありがとうございます。

+0

「新しい」キャッシュを呼び出さないでください。これはC++のキーワードであり、C++でコードをコンパイルしようとすると痛みの世界を導入するだけです。 – zmbq

+0

newは、最初はひどい変数名です(あなたは常にわかりやすい名前を使うべきです)が、CでプログラミングするときにはC++に準拠するようにあなたのコードを変更するのはひどい推論です。私はあなたがそれまでのコードをコンパイルするのを気にしていれば、C++を使うと思います。 – Rabbit

+0

これはわかりませんでした。すべてのコードでそれを変更しようとしています。ありがとう – de1337ed

答えて

2

"What is the difference between a cache->lines and a cache->lines[0]?"

cache->linesであるあなたの2次元配列であるstruct line_elems**です。実際には、2D配列の最初の要素へのポインタです。 cachecache_handler* = struct cache_handlerのメンバーにアクセスしているため、オペレータ->が使用されています。

cache->lines[0]struct line_elems*で、インデックス0の1D配列です.2D配列の最初の要素へのポインタでもあります。このメモリの解放すると、あなたの割り当てよりも、逆の順序を持​​っている必要があることを

注:

line **new_line = malloc((1 << s) * sizeof(*new_line)); 
for(i = 0; i < (1 << s); i++) 
    new_line[i] = malloc(E * sizeof(struct line_elems)); 

あなたの自由それぞれ最初new_line[i]とその後のあなたの無料new_line自体:

for(i = 0; i < (1 << s); i++) 
    free(new_line[i]); 
free(new_line); 
+0

私は実際に行を検索する場合は、 "lines [i] .tag = 1234"のようなものを入れますか?同様に各行の特定のフィールドにアクセスしますか? – de1337ed

+0

@ de1337ed:はい。 – LihO

+0

申し訳ありませんが、最後の質問、私は '無料'機能を作成しようとしています、私は基本的に私のキャッシュを解放する次の行があります:フリー(new_cache-> lines [i] [j]);しかし、私がこれを試してみると、うまくいきません。 (注、i、jは入れ子になったforループにあります) – de1337ed

2

->オペレータが参照解除linesでない場合、逆参照cacheです。これは、cacheもポインタ(mallocへの呼び出しによって作成される)であるため、必要です。したがって、フィールドのいずれかにアクセスする前に逆参照する必要があります。

cache->linesline **

cache->lines[0]あるline *

1

はい、の参照cache-> lines [0]は実際にあなたの割り当てられた配列の配列へのポインタを返すので、あなたの呼び出し例は実際にそれを行う正しい方法です。

cache-> linesは、ポインタの割り当て配列(mallocへの2番目の呼び出し)であることに注意してください。単に、十分なスペースを割り当てます。2^s * the_size_of_a_pointer

残りのmallocsは、E * size_of_a_lineに十分なスペースを割り当てます。あなたがキャッシュポインタデリファレンス(->を使用)してから([0]を使用して)行がポインタ欽慕とき

それでは、あなたはEラインへのメモリポインタで終わります。

次に、あなたの機能で、あなたは最初の行を取得するlines[0]を使用することができ、かつlines[E-1]はラインポインタの配列は、(cache->linesデータポインタへ[]オペレータに基づく)に渡されたものは何でもの最後に到達するために。