声明堆栈上的结构

时间:2016-09-22 06:04:07

标签: c struct

这是来自Zed Shaw的艰难学习方法:

#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->db->rows[i]。在调用database_create()之前,我已初始化conn->db = malloc(sizeof(struct Database));

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

谢谢!

1 个答案:

答案 0 :(得分: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->db->rows[i] = &addr;

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

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