【问题标题】:Declaring a struct on the stack在堆栈上声明一个结构
【发布时间】:2017-01-30 13:54:47
【问题描述】:

这是来自 Zed Shaw 的 Learn C the Hard Way:

#define MAX_DATA 15
#define MAX_ROWS 100


struct Address {
    int id;
    int set;
    char name[MAX_DATA];
    char email[MAX_DATA];
};

struct Database {
    struct Address rows[MAX_ROWS];
};

struct Connection {
    FILE *file;
    struct Database *db;
};


void Database_create(struct Connection *conn)
{
    int i = 0;

    for (i = 0; i < MAX_ROWS; i++) {

        struct Address addr = {.id = i, .set = 0};

        conn->db->rows[i] = addr;
    }
}

对于struct Address addr = {.id = i, .set = 0} 行,我们在堆栈上声明addr,并将该结构分配给conn-&gt;db-&gt;rows[i]。在调用database_create()之前,我已经初始化了conn-&gt;db = malloc(sizeof(struct Database));

一旦函数退出,addr 会被清理,因为它在堆栈上。 addr 的值如何在 conn-&gt;db-&gt;rows[i] 中持续存在?分配是否创建了存储在addr 中的数据的副本并将其存储在conn-&gt;db-&gt;rows[i] 的堆位置上?

谢谢!

【问题讨论】:

  • 它被复制(即“按值”)到conn-&gt;db-&gt;rows[i]
  • "我们在堆栈上声明 addr" 在 C 中不能保证这一点。"addr 的值如何保持" 您分配了一个 struct Database 并写入它。它会持续存在,因为mallocated 内存会持续到freed。
  • @Rhymoid 当我在函数中声明一个变量(不调用 malloc)时,它不能保证存储在堆栈中吗? stackoverflow.com/questions/10916799/…
  • @user2635088:C 语言标准没有规定必须在哪些内存段中分配变量。它取决于平台(编译器/链接器)。然而,大多数(甚至所有)常见实现在堆栈上分配非静态局部变量,在数据部分分配全局和/或静态变量,在堆中分配运行时内存块,这是真的。
  • @barakmanos 当您谈论 c 的实现时,这是指编译器-ISA 组合吗?即对于我的机器,它将是 gcc 和 x86_64?

标签: c struct


【解决方案1】:

是的,这是一份复制作业。

在这种情况下,您有一个结构数组,其大小等于MAX_ROWS*sizeof(struct Address)。所以,无论如何,它都有足够的空间。

考虑以下几点:

struct coord{int x,y;};
struct coord a = {0,0};
struct coord b;
b = a; //This is a copy assignment

这里,数组的每一行都有一个完整的结构,你把addr的值复制到里面。


不属于复制赋值的是指针数组:

struct Database {
    struct Address *rows[MAX_ROWS];
};

之后,conn-&gt;db-&gt;rows[i] = &amp;addr;

显然,在这种情况下您会遇到问题,因为指针引用的值是未定义的,并且不同的行很可能包含相同的地址。但是,如果您使用动态分配,那就没问题了。

如果您想查看在不使用指针时数组确实包含MAX_ROWS 结构这一事实,您可以尝试在这两种情况下都显示sizeof(*(conn-&gt;db))sizeof(conn-&gt;db-&gt;rows)

【讨论】:

    猜你喜欢
    • 2018-06-13
    • 2014-11-30
    • 2017-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-01
    • 1970-01-01
    • 2016-02-04
    相关资源
    最近更新 更多