2016-10-19 5 views
6

システムコールで行われ、構造体*のためにメモリを割り当てる必要がある練習を完了しようとしています。私のコードは次のとおりです。malloc()の代わりにmmap()を使用する

myStruct * entry = (myStruct *)mmap(0, SIZEOF(myStruct), PROT_READ|PROT_WRITE, 
MAP_ANONYMOUS, -1, 0); 

明確にするために、私はmalloc()を使用することはできませんが、mmap()を使用することができます。私はNetbeansのWindowsでこれに問題はなかったが、今はコンパイルしてUbuntuのコマンドラインから実行していますが、アクセスしようとするたびに「Segmentation Fault」が表示されています。

この方法でメモリを割り当てる有効な方法はmmap()ですか?私が心配していたのは、最初にmmap()コールごとに大きなメモリを割り当てようとしていたからです。今は実行できません。

また、私のmmapが返されたエラーは22 - 無効な引数です(質問を書く際にいくつかのトラブルシューティングを行ったため、エラーチェックは上記のコードに含まれていません)。アドレスが0で、カスタムSIZEOF()関数は他のmmap引数でも機能しますが、MAP_ANONYMOUSを使用しているため、fdoffsetのパラメータはそれぞれ-1と0でなければなりません。

PROT_READ|PROT_WRITEセクションに何か問題がありますか?

+2

'4096'や' 8192'や 'SIZEOF(myStruct)'の代わりに2の累乗を使うと、それはうまくいくのでしょうか? –

+1

私はあなたの 'SIZEOF()'からのエラーだと思います。'MAP PRIVATE'を追加してください。 –

+0

' SIZEOF() 'は正しくありません。実際のアイテムの綴りは' sizeof() 'I.Eです。すべて小文字です。 – user3629249

答えて

6

フラグにMAP_PRIVATEを指定する必要があります。 manual pageから

myStruct * entry = (myStruct *)mmap(0, SIZEOF(myStruct), 
     PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 

flags引数は、マッピングの更新が他の同じ領域をマッピングするプロセス、及び 更新は、基礎となるファイルに通って運ばれているかどうかに見える か否かを判定する。この動作は はflagsに以下の値を正確に一つ含むによって決定されます。

あなたはフラグMAP_PRIVATEまたはMAP_SHAREDの正確に一つを必要とする - しかし、あなたがそれらのいずれかを与えていません。

完全な例:

#include <sys/mman.h> 
#include <stdio.h> 

typedef struct 
{ 
    int a; 
    int b; 
} myStruct; 

int main() 
{ 
    myStruct * entry = (myStruct *)mmap(0, sizeof(myStruct), 
      PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 

    if (entry == MAP_FAILED) { 
     printf("Map failed.\n"); 
    } 
    else { 
     entry->a = 4; 
     printf("Success: entry=%p, entry->a = %d\n", entry, entry->a); 
    } 
    return 0; 
} 

(上記は、当然のMAP_PRIVATEせずに、あなたがMCVEとして提供しているかもしれないものの良い例である。これは、それははるかに簡単に他の人があなたを助けるようになり、。彼らはあなたが行ったことを正確に見ることができ、提案された解決策をテストすることができます。

+0

これはそれだった、私はマニュアルを誤解した!私はMAP_PRIVATEで始まり、MAP_ANONYMOUSに移動し、両方が必要でした...ありがとうございました。 –

3

mmap()のマニュアルページには、flags引数にMAP_SHAREDMAP_PRIVATEのいずれかを正確に指定する必要があると記載されています。あなたのケースでは、malloc()ように行動するために、あなたはMAP_PRIVATEたいと思う:

myStruct *entry = mmap(0, sizeof *entry, 
         PROT_READ|PROT_WRITE, 
         MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); 

(私も有害なキャストを省略し、そのタイプではなく、実際の変数へsizeofを照合することによって、この多くの慣用的なCを作りました) 。

+0

ありがとう!私はマニュアルの読解スキルに取り組むべきです。 –

関連する問題