C 堆栈与基本数据类型的内存分配

C 堆栈与基本数据类型的内存分配,c,memory-management,malloc,C,Memory Management,Malloc,在C中声明结构时,请说: typedef struct my_stuct { int x; float f; } STRT; 如果要创建并使用此结构的实例,我们需要显式调用malloc,获取指向此结构的内存位置的指针,然后才能实际初始化/使用结构的任何成员: STRT * my_struct_instance = (STRT *) (malloc(sizeof(STRT))); 但是,如果我声明一个基本数据类型,比如int a;然后要初始化它或对它执行任何其他操作,在对它执行任何操作之前

在C中声明结构时,请说:

typedef struct my_stuct {
 int x;
 float f;
} STRT;
如果要创建并使用此结构的实例,我们需要显式调用malloc,获取指向此结构的内存位置的指针,然后才能实际初始化/使用结构的任何成员:

STRT * my_struct_instance = (STRT *) (malloc(sizeof(STRT)));
但是,如果我声明一个基本数据类型,比如int a;然后要初始化它或对它执行任何其他操作,在对它执行任何操作之前,我不需要通过调用malloc显式地为它分配mempory空间:

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

你能解释一下这种不一致的原因吗?谢谢大家!

没有不一致之处。这两种方法中的每一种都可用于基本体和结构:


没有不一致之处。这两种方法中的每一种都可用于基本体和结构:

你可以做:

int i;

就像你能做的一样

STRT my_struct_instance;

你可以做:

int i;

就像你能做的一样

STRT my_struct_instance;


两种方法都可以,没有任何不一致之处

堆叠


两种方法都可以,没有任何不一致之处

堆叠

使用动态存储

int a;

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

因此,没有不一致之处。说有一个就好像说苹果和桔子之间有不一致之处——但当然有,因为你是在比较苹果和桔子。问题的其他部分没有意义,因为它们是基于苹果和橙子是一回事的假设

使用动态存储

int a;

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


因此,没有不一致之处。说有一个就好像说苹果和桔子之间有不一致之处——但当然有,因为你是在比较苹果和桔子。这个问题的其他部分没有意义,因为它们是基于苹果和橙子是一回事的假设。

在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

不知道这是否回答了您的问题。

在您的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

不知道这是否回答了您的问题。

STRT object;工作正常,但成员将未初始化。STRT object={3,5};在那里,初始化为@user721998,int i;不初始化i,malloc也不初始化它。@user721998不初始化。您可以像int一样将结构放在堆栈上。@Griwes,这将是位置:STRT object;工作正常,但成员将未初始化。STRT object={3,5};在那里,初始化为@user721998,int i;不初始化i,malloc也不初始化它。@user721998不初始化。您可以像int一样将结构放在堆栈上。@Griwes,这就是位置:假设我要声明结构变量,并用两个单独的步骤初始化它,如下所示:STRT struct_var;结构变量->x=10;结构变量->y=10.0;除非我没有使用malloc显式地为“struct_var”分配内存位置,否则这是行不通的。但是,您可以在基本数据类型中轻松地实现这一点,如:inti;i=10@user721998,这不是初始化。这是分配给成员的。@NPE:replacement->with。有效,但为什么?感谢你们的帮助@user721998:s->x与*s.x相同,即仅当s是指针时才有效。在这里,它不是。用于选择结构或联合的成员,如s1.x中所示。如果s1是指针,则必须首先取消对指针的引用,如*s1.x。这样做非常常见,以至于有一个快捷方式->操作符用于选择指向结构的指针的成员,因此您可以执行s1->xLet的“我想要dec”
放大结构变量并用两个独立的步骤初始化它,如下所示:STRT struct_var;结构变量->x=10;结构变量->y=10.0;除非我没有使用malloc显式地为“struct_var”分配内存位置,否则这是行不通的。但是,您可以在基本数据类型中轻松地实现这一点,如:inti;i=10@user721998,这不是初始化。这是分配给成员的。@NPE:replacement->with。有效,但为什么?感谢你们的帮助@user721998:s->x与*s.x相同,即仅当s是指针时才有效。在这里,它不是。用于选择结构或联合的成员,如s1.x中所示。如果s1是指针,则必须首先取消对指针的引用,如*s1.x。这样做非常常见,以至于有一个快捷方式->操作符用于选择指向结构的指针的成员,因此您可以执行s1->x*b={1,1.0};你确定吗?不客气,也许你指的是复合文字*b=STRT{1,1.0};在C99*b={1,1.0}中有效;你确定吗?不客气,也许你指的是复合文字*b=STRT{1,1.0};在C99中有效
int a;
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