【问题标题】:memory allocation for stack vs primitive datatypes堆栈与原始数据类型的内存分配
【发布时间】:2013-01-04 18:46:31
【问题描述】:

在 C 中声明一个结构时,说:

typedef struct my_stuct {
 int x;
 float f;
} STRT;

如果我们想创建这个结构的一个实例并使用它,我们需要显式调用 malloc,获取一个指向这个结构的内存位置的指针,然后才能真正初始化/使用结构的任何成员:

STRT * my_struct_instance = (STRT *) (malloc(sizeof(STRT)));

但是,如果我声明一个原始数据类型(比如“int a;”)然后想要对其进行初始化(或对其执行任何其他操作),我不需要通过调用 malloc 显式为其分配内存空间在对其执行任何操作之前:

// we do not need to do a malloc(sizeof(i)) blah blah here. Why?
i = 10;

您能否解释一下造成这种不一致的原因是什么?谢谢!

【问题讨论】:

  • STRT object; 工作正常,但成员将未初始化。
  • STRT object = {3, 5}; 那里,已初始化。
  • @user721998, int i; 不初始化 imalloc 也不初始化它。
  • @user721998 你不知道。您可以像 ints 一样将 structs 放入堆栈。
  • @Griwes,这里就是:stackoverflow.com/questions/605845/…

标签: c memory-management malloc


【解决方案1】:

没有不一致。这两种方法中的每一种都可以用于原语和structs

  STRT s1 = {1, 2};
  int i1 = 1;

  STRT *s2 = (STRT *)malloc(sizeof(STRT));
  int *i2 = (int *)malloc(sizeof(int));
  ...

【讨论】:

  • 假设我想声明结构变量并在两个单独的步骤中初始化它,如下所示:STRT struct_var;结构变量->x = 10; struct_var->y = 10.0;除非我没有使用 malloc() 显式分配“struct_var”内存位置,否则这是行不通的。但是,您可以在原始数据类型中轻松做到这一点: int i; i=10;
  • @user721998,这不是初始化。这是分配给成员的。
  • @NPE:替换 -> 为 .有效,但为什么呢?感谢您的帮助!
  • @user721998: s->x(*s).x 相同,即它仅在 s 是指针时才有效。在这里,它不是。
  • @user721998 在 C 中,. 用于选择结构(或联合)的成员,如 s1.x。如果 s1 是指针,则必须先取消引用指针,例如 (*s1).x 。这样做很常见,以至于有一个快捷方式(-> 运算符)用于选择指向结构的指针的成员,所以你可以这样做 s1->x
【解决方案2】:

你可以这样做:

int i;

int *i = (int*) malloc(sizeof(int));

就像你可以做的那样

STRT my_struct_instance;

STRT * my_struct_instance = (STRT *) (malloc(sizeof(STRT)));

【讨论】:

    【解决方案3】:

    在您的 malloc 示例中,您使用的是指针。正如您所说,这种不一致是因为可以通过多种方式初始化指针。它并不总是由新的内存分配初始化,但它也可以初始化为指向现有的内存块。因此,语言不可能假定变量应该在堆上分配:

    STRT* my_struct_instance; // here I assume (incorrectly) that it is automatically allocated on the heap
    my_struct_instance->x = 0; // ERROR: uninitialized use of that variable
    

    不知道这是否能回答你的问题。

    【讨论】:

      【解决方案4】:

      两种方式都可以,没有任何不一致的地方。

      int* a= malloc(sizeof(int));
      *a=10;
      STRT* b= malloc(sizeof(STRT));
      b->x=1; 
      b->f=1.0;
      

      堆栈

      int a=10;
      STRT b= {1, 1.0};
      

      【讨论】:

      • *b= {1, 1.0};你确定吗?
      • 不客气,也许你的意思是复合文字 *b = (STRT){1, 1.0}; 在 C99 中有效
      【解决方案5】:
      STRT * my_struct_instance = (STRT *) (malloc(sizeof(STRT)));
      

      使用动态存储;

      int a;
      

      使用自动存储(我现在使用 C++ 名称,但在 C 中可能类似地调用它)。所以,这是两个完全不同的东西。 int a; 是本地的,在(在大多数实现中)堆栈上(尽管堆栈不是相关的实现细节); SRTR * [...] 是动态的,在(在大多数实现中)堆上(尽管同样,堆不是相关的实现细节)。

      所以,没有不一致。说有一个就像说苹果和橙子之间存在不一致 - 但当然有,因为您正在比较苹果和橙子。 (问题的其他部分没有意义,因为它们是基于假设苹果和橙子是一回事)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-28
        • 1970-01-01
        • 2023-03-03
        • 2011-09-06
        • 2018-07-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多