2016-09-22 99 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)