malloc返回指向已分配内存的指针

时间:2016-04-23 07:09:53

标签: c malloc

很长一段时间以来我写过C.我的理解是malloc返回指向新分配的内存区域的指针,该内存区域与之前的malloc反应不重叠。但是,我的程序(下面)似乎显示malloc返回指向已分配区域中间的指针!

#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          0x7fa68bc03210
&(foo->bar)  0x7fa68bc03210
arr[0] = 42

我做错了什么?

3 个答案:

答案 0 :(得分: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

不要使用相同标识符的两倍,你会收到不好的惊喜。

答案 1 :(得分: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

答案 2 :(得分: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.4

在ubuntu linux 14.04下编译了这个

使用:

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

然后

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

然后用

运行它
./myfile