2016-12-03 17 views
-1

私はUnix v6ファイルシステムのモデルを作成しています。私は最初に利用可能な空きブロックをファイルに書き込んでから、必要なときに同じものを読み込んで割り当てようとしました。私は100ブロックの空き配列を持っているので、空きブロックの数が100を超えると、現在の空き配列はfree [0]のメモリブロックに書き込まれ、新しい空きブロックはfree [0] 。以下は、私が書いたサンプルコードです。C言語を使用してファイルに配列を書き込む

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <sys/types.h> 
#include <sys/stat.h> 

void splitCommand(char**,char*, char*); 
unsigned short freeArr[100]; 
unsigned short nfree=1,fd; 
int main() 
{ 

    fd = open("v6", O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IEXEC | S_IWRITE); 
    freeArr[0] = 0; 
    for (int i = 28; i < 5000; i++) 
    { 
     addFreeBlock(i); 
    } 

    unsigned short free1=0 ; 
    lseek(fd, 3127 * 512, SEEK_SET); 
    read(fd, &(nfree), sizeof(unsigned short)); 
    printf("%d\n",nfree); 
    for(int i=0; i<nfree; i++) 
    { 
     read(fd, &free1, sizeof(unsigned short)); 
     printf("%d\n",free1); 
    } 
} 

void addFreeBlock(int block_no) 
{ 
    if(block_no==3127) 
    { 
     int a=0; 
    } 

    if (nfree == 100) 
    { 
     lseek(fd, block_no * 512, SEEK_SET); 
     write(fd, &(nfree), sizeof(unsigned short)); // copy nfree into free array 
     write(fd, freeArr, 200);// copy free array 
     nfree=0; 
    } 
    freeArr[nfree] = block_no; 
    nfree++; 
} 

合計5000ブロックあるとします。各ブロックの長さは512バイトです。私は他の目的のために最初の27ブロックを使用しているので、私は28から5000までのブロックを書いています。

すべてのブロックを書き込んだ後、ランダムな場所に格納されたブロックを読み込もうとしました。私が3027に格納されたブロックを読み込もうとしたとき、私は2927,2928,2929、...、3026から番号をつけた100ブロックを読み取ることができます。しかし、3127に格納されたブロックを読み込むと、3027、3028、3029、...、3081のブロックだけを読み込むことができます。残りはランダムです。私は他のポジションでもやってみました。それはそれらのいくつかのために働く。

どこに間違っていたのか教えていただけますか?

+0

'nfree'は' int'で、 'sizeof(unsigned short) 'を使用すると' sizeof(nfree) 'が代わりに使用されます。 –

+1

猫はスペースバーに座っていますか?とにかく 'open'の戻り値をチェックしてみませんか? –

+0

@EdHeal、 'open'と' read'と 'write'から...私はすべてが重要だと思います。 –

答えて

1

申し訳ありませんが、これは実際の回答ではありませんが、私はこれをコメントに書き込めません。しかし、それは何とか答えます。

あなたのコードは正しく動作し、私はvalgrindでテストしましたが、エラーはありませんが、それについて多く考える必要があります。あなたが本当にが何より良い解決策はありません知っているとき、あなたのコード内の単一のグローバル変数のための必要はありません

は、あなたが唯一のグローバル変数を使用する必要があり、これは、あなたの正確なコードの改良版である

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <stdint.h> 

uint16_t add_free_block(int fd, int block_number, uint16_t *free_blocks, uint16_t free_block_count); 

int main(void) 
{ 
    uint16_t free_blocks[100]; 
    uint16_t free_block_count; 
    int fd; 

    fd = open("v6", O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IEXEC | S_IWRITE); 
    if (fd == -1) 
     return -1; 
    free_blocks[0] = 0; 

    free_block_count = 1; 
    for (int i = 28; i < 5000; i++) { 
     free_block_count = add_free_block(fd, i, free_blocks, free_block_count); 
    } 

    lseek(fd, 3127 * 512, SEEK_SET); 
    read(fd, &free_block_count, sizeof(uint16_t)); 

    printf("%d\n", free_block_count); 
    for (int i = 0; i < free_block_count; i++) { 
     uint16_t block_number;   
     if (read(fd, &block_number, sizeof(uint16_t)) == sizeof(uint16_t)) { 
      printf("%d\n", block_number); 
     } 
    } 
    close(fd); 
    return 0; 
} 

uint16_t 
add_free_block(int fd, int block_number, uint16_t *free_blocks, uint16_t free_block_count) 
{ 
    if (free_block_count == 100) { 
     lseek(fd, block_number * 512, SEEK_SET); 

     write(fd, &free_block_count, sizeof(uint16_t)); 
     write(fd, free_blocks, free_block_count * sizeof(uint16_t)); 

     free_block_count = 0; 
    } 
    free_blocks[free_block_count] = block_number; 

    return free_block_count + 1; 
} 
(マイナーだが重要な も、私はファイルディスクリプタを閉じ)グローバル変数と

write()のような他の戻り値もチェックする必要があります。なぜなら、私はすべてをやりたいとは思っていなかったからです。

実際の問題は、このコードではなく、プログラムの残りの部分にあります。したがって、実際のコードをPOSTして、問題の内容を推測しないようにしてください。一般的に

、これらは私の勧告

  1. あるあなたはMUST 非常に非常には確信している場合を除き、グローバル変数を使用しないでください。
  2. 関数プロトタイプを追加します。
  3. コンパイラの警告を無視しないでください。
  4. 戻り値が返ってきたことがわからない場合は、返される関数の戻り値を常にチェックしてください。
  5. 使用するすべての関数のすべてのドキュメントを注意深く読んでください。
+0

実際のコードは1000行以上です。だから私はその質問を複雑にしないと思った。また、私はあなたのコードをWindowsでcodeblocksを使って実行しました。私は同じ出力3027、3028、3029、....、3081、...乱数を得ました。あなたはあなたの出力を投稿してください。 – ArunKumar

+0

そして、[valgrind](http://www.valgrind.org)をあなた自身で使い、あなたのコードに誤りがないかチェックしてください。そして私の出力は '100 3027 3028 ... 3126'です。 –

+0

窓の上には、バググリンドがありません。コードブロックはこれをどのようにコンパイルしていますか? –

関連する問題