首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用malloc和不带malloc创建结构的差异

问使用malloc和不带malloc创建结构的差异
EN

Stack Overflow用户
提问于 2020-02-02 19:09:26
回答 4查看 2.9K关注 0票数 5

有谁能给我解释一下使用malloc和没有malloc的结构之间的区别吗?什么时候应该使用malloc,什么时候应该使用常规初始化?

例如:

代码语言:javascript
复制
struct person {

    char* name;

};

struct person p = {.name="apple"};

struct person* p_tr = malloc(sizeof(struct person));
p_tr->name = "apple";

两者究竟有甚麽分别呢?什么时候会使用一种方法而不是其他方法呢?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2020-02-02 19:42:10

如果假设这两个示例都发生在函数中,则在:

代码语言:javascript
复制
struct person p = {.name="apple"};

C实现自动为p分配内存,并在函数执行结束时释放它(或者,如果语句位于嵌套在函数中的块内,则在该块的执行结束时)。在以下情况下,这是有用的:

,

  • ,您正在处理的对象的大小适中。(对于大对象,使用大量的基字节内存,malloc可能更好。阈值根据circumstances.)
  • You一次处理少量对象的不同而有所不同。

在:

代码语言:javascript
复制
struct person* p_tr = malloc(sizeof(struct person));
p_tr->name = "apple";

程序显式地请求对象的内存,程序在使用对象时通常应该使用free释放该内存。在以下情况下,这是有用的:

  • 对象必须返回给函数的调用方。上面使用的自动对象将不再存在(在计算的C模型中;计算机中的实际内存不会停止存在--只是不再为该对象保留),但这个分配的对象将继续存在,直到程序释放它(或者结束execution).
  • The对象非常大)。(一般来说,C实现提供了比自动objects.)
  • The程序更多的malloc分配内存,这取决于环境,如从输入中创建链接列表、树或其他结构,而输入在读取之前不知道这些对象的大小。

注意,struct person p = {.name="apple"};用"apple"初始化name成员,并将所有其他成员初始化为零。但是,使用malloc并分配给p_tr->name的代码不会初始化其他成员。

如果struct person p = {.name="apple"};出现在函数之外,那么它将创建一个具有静态存储持续时间的对象。它将在程序执行期间存在。

与struct person* p_tr = malloc(sizeof(struct person));不同,最好使用struct person *p_tr = malloc(sizeof *p_tr);。对于前者,对p_tr的更改需要在两个地方进行编辑,这就允许人类有机会犯错误。对于后者,仅在一个地方更改p_tr类型仍然会导致请求的大小正确。

票数 3
EN

Stack Overflow用户

发布于 2020-02-02 19:27:52

具有类似的数据结构;

代码语言:javascript
复制
struct myStruct {
    int a;
    char *b;
};

struct myStruct p;  // alternative 1
struct myStruct *q = malloc(sizeof(struct myStruct));  // alternative 2

  • 备选方案1:在堆栈上分配内存空间的myStruct宽度,并将结构的内存地址交给您(即&p给出结构的第一个字节地址)。如果它是在函数中声明的,则其生命周期将在函数退出时结束(即,如果函数超出了作用域,则无法到达it).
  • Alternative 2:在堆上分配内存空间的myStruct宽度,在堆栈上分配(struct myStruct*)类型的内存空间的指针宽度。堆栈上的指针值被分配给结构的内存地址的值(在堆上),这个指针地址(而不是实际的struct地址)返回给您。直到你使用free(q).

,生命的时间才会结束

在后一种情况下,例如,myStruct位于内存地址0xabcd0000上,q位于内存地址0xdddd0000上;然后,将内存地址0xdddd0000上的指针值赋值为0xabcd0000,并将其返回给您。

代码语言:javascript
复制
printf("%p\n", &p); // will print "0xabcd0000" (the address of struct)

printf("%p\n", q);  // will print "0xabcd0000" (the address of struct)
printf("%p\n", &q); // will print "0xdddd0000" (the address of pointer)

指你的第二部分;何时使用:

  • 如果该结构位于函数中,并且在函数退出后需要使用它,则需要对其进行malloc。您可以通过返回指针来使用结构的值,例如:return q;.
  • If此结构是临时的,您不需要它的值之后,您不需要malloc内存。

使用示例:

代码语言:javascript
复制
struct myStruct {
    int a;
    char *b;
};

struct myStruct *foo() {
    struct myStruct p;
    p.a = 5;
    return &p; // after this point, it's out of scope; possible warning
}

struct myStruct *bar() {
    struct myStruct *q = malloc(sizeof(struct myStruct));
    q->a = 5;
    return q;
}

int main() {
    struct myStruct *pMain = foo();
    // memory is allocated in foo. p.a was assigned as '5'.
    // a memory address is returned.
    // but be careful!!!
    // memory is susceptible to be overwritten.
    // it is out of your control.

    struct myStruct *qMain = bar();
    // memory is allocated in bar. q->a was assigned as '5'.
    // a memory address is returned.
    // memory is *not* susceptible to be overwritten
    // until you use 'free(qMain);'
}
票数 4
EN

Stack Overflow用户

发布于 2020-02-02 19:13:51

代码语言:javascript
复制
struct person p = {.name="apple"};

^这是对person类型的变量/实例的自动分配。

代码语言:javascript
复制
struct person* p_tr = malloc(sizeof(person));

^这是对person类型的变量/实例的动态分配。

静态内存分配发生在编译时。动态内存分配是指当程序执行该指令行时,它在运行时分配内存。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60029592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档