2016-09-22 101 views
0

这是Zed的Shaw的了解C对坚硬方式:声明一个结构栈

#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},我们在栈上声明地址,我们正在分配该结构来conn->db->rows[i] 。在调用database_create()之前,我已经初始化了conn->db = malloc(sizeof(struct Database));

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

谢谢!

+2

它被复制(即“按值”)到'conn-> db-> rows [i]'中。 –

+0

“我们在堆栈上声明addr”对于C中没有保证。“addr的值如何保持”您分配了一个'struct Database'并写入它。它持续存在,因为'malloc'内存一直存在,直到'free'd。 – 2016-09-22 06:09:12

+0

@Rhymoid当我声明一个函数内的变量(不调用malloc)时,它不保证被存储在堆栈中? http://stackoverflow.com/questions/10916799/how-to-create-a-struct-on-the-stack-in-c – user2635088

回答

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;

很明显,你会碰上这种情况的问题,作为值引用的指针未定义,并且不同的行很可能包含相同的地址。但是,如果您使用动态分配,这将很好。

如果你想看到这样一个事实,即在不使用指针时数组确实保存了MAX_ROWS结构,你可以尝试在两种情况下都显示sizeof(*(conn->db))sizeof(conn->db->rows)