2016-04-23 10 views
1

私はCを書いて以来、長い時間がかかりました。私の理解は、mallocは、以前にmallocと反応しなかった新たに割り当てられたメモリ領域へのポインタを返します。しかし、私のプログラム(下記)は、既に割り振られた領域の中央にポインタを返すことを示しているようです!mallocmallocは割り当てられたメモリへのポインタを返す

#include <stdio.h> 
#include <stdlib.h> 

typedef struct { 
    int* bla; 
    int baz; 
    int qux; 
    int bar; 
} foo; 

int main() { 
    foo* foo = malloc(sizeof(foo)); 
    int* arr = malloc(sizeof(int) * 10); 
    // my understanding of malloc is that `foo` and `bar` now point to 
    // non-overlapping allocated memory regions 

    printf("arr   %p\n", arr);   // but these print 
    printf("&(foo->bar) %p\n", &(foo->bar)); // the same address 

    foo->bar = 42; 
    printf("arr[0] = %d\n", arr[0]); // prints 42 

    return 0; 
} 

私はこれをコンパイルし、実行している:私は間違って何をやっている

$ cc --version 
Apple LLVM version 7.3.0 (clang-703.0.29) 
Target: x86_64-apple-darwin15.3.0 
Thread model: posix 
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin 
$ cc  main.c -o main 
$ ./main 
arr   0x7fa68bc
&(foo->bar) 0x7fa68bc
arr[0] = 42 

+3

でそれを実行した;'回避したであろうこのエラー –

+1

彼はうれしいことに 'foo * foo = malloc(sizeof * foo);' –

+0

'foo * foo =(foo *)malloc(sizeof(foo))'コンパイラが '(foo *)'にエラーを出すので、この問題も回避していました。いくつかのポスターは "mallocをキャストしない"と言っているが、アドバイスの第2部分を忘れる( 'sizeof'式を変更する)のが好きです。 'malloc(sizeof(Type))'は '(Type *)malloc(sizeof(Type))'よりエラーが発生しやすくなります。 –

答えて

5

これはなんですか?

foo* foo = malloc(sizeof(foo)); 

別の識別子を使用してください。

foo* variable = malloc(sizeof(foo)); 

ちょうど私がこのmain()テストしてください取得するには:

int main() { 
    printf("sizeof(foo)=%zu\n", sizeof(foo)); 
    foo* foo = malloc(sizeof(foo)); 
    printf("sizeof(foo)=%zu\n", sizeof(foo)); 
} 

出力(LLP64と64-ビット)を:

sizeof(foo)=24 
sizeof(foo)=8 

は二度同じ識別子を使用しないでください、あなたは悪い驚きを得ること。

+0

これは 'foo'と* pray *と呼ばれています。あなたはいつもそれを見る... –

+0

ああ*もちろん! 'sizeof'は型と変数に適用できます!私が考えていたことは何でしょう?私はウォールが私にこのことを警告して欲しい! – jameshfisher

+0

@ DavidC.Rankin私の主な関心事は、 '-Wextra'' -Wall'でも私のgccは警告なしでコードをコンパイルします。 – jdarthenay

1

typdefエイリアスとインスタンスの宣言が同じ名前で衝突することはありません。もともと持っていたことをすることはできますが、推薦することはできませんが、タイプから取得しようとする代わりに、変数からサイズを取得してください。具体的に:

foo *foo = malloc (sizeof *foo); 

あなたは完全な例で確認することができます。

次のコード

お知らせインスタンスの一意の名前を使用して

#include <stdio.h> 
#include <stdlib.h> 

typedef struct { 
    int *bla; 
    int baz; 
    int qux; 
    int bar; 
} foo; 

int main (void) { 

    foo *foo = malloc (sizeof *foo); 
    int *arr = malloc (sizeof *arr * 10); 

    printf ("arr   %p\n", arr); 
    printf ("&(foo->bar) %p\n", &(foo->bar)); 

    foo->bar = 42; 
    printf ("foo->bar = %d\n", foo->bar); 

    return 0; 
} 

出力例

$ ./bin/foofoo 
arr   0x17f3030 
&(foo->bar) 0x17f3020 
foo->bar = 42 
0

foo

#include <stdio.h> 
#include <stdlib.h> 

typedef struct 
{ 
    int* bla; 
    int baz; 
    int qux; 
    int bar; 
} foo; 

int main() 
{ 
    foo* myfoo = malloc(sizeof(foo)); 
    int* arr = malloc(sizeof(int) * 10); 

    // my understanding of malloc is that `foo` and `bar` now point to 
    // non-overlapping allocated memory regions 

    printf("arr   %p\n", arr);   // but these print 
    printf("&(foo->bar) %p\n", &(myfoo->bar)); // the same address 

    myfoo->bar = 42; 
    printf("arr[0] = %d\n", arr[0]); // prints 42 

    return 0; 
} 

出力は次のようになります。私が期待する正確に何である

arr   0x1578030 
&(foo->bar) 0x1578020 
arr[0] = 0 

これは、gcc 4.8でubuntu linux 14.04でコンパイルしました。4

使用:次いで

gcc -ggdb -c -Wall -Wextra -pedantic -Wconversion -std=gnu99 myfile.c -o mybile.o 

gcc -ggdb -std=gnu99 myfile.o -o myfile 

推奨パターン `P = malloc関数(はsizeof * pを)使用

./myfile 
関連する問題