2016-03-31 57 views
1

我已經聲明瞭struct FOO這樣的:堆對象如何使用堆棧中的數據?

struct foo { 
    const char* name_lower; 
    const char* name_caps 
    //.. 
}; 

我在堆上動態創建的foo實例,並要保存在name_lowername_caps成員變量的值。這是由bar

void bar(foo* entry, const char* str, int delimiter_pos) { 

    char l[2] = {str[caps_pos-1], '\0'}; // create new string 
    char c[2] = {str[caps_pos+1], '\0'}; 

    entry->name_lower = &l[0]; // assign these strings the foo instance 
    entry->name_caps = &c[0]; 
} 

我擔心的函數來完成,因爲我不知道這是否代碼將崩潰做。臨時創建的陣列lc將保存在堆棧中。一旦函數終止,堆棧將被清除,cl可能會消失。

這是否意味着foo實例將失去它的名稱,即它的引用?如果是這樣,我該如何解決這個問題?

+0

Google針對「動態內存分配」 - http://www.programiz.com/c-programming/c-dynamic-memory-allocation –

+0

我知道關於動態內存分配的原則。這是否意味着我必須通過調用malloc來將l和c存儲在堆上? – null

+0

是的,確切地說。否則它們將指向流從「bar」返回後將包含未定義值的地址。 –

回答

0

你應該改用char *l = (char *)malloc(2 * sizeof(char));然後初始化它;同樣爲char *c。然後設置entry->name_lower = l; entry->name_caps = c;

分配時請確保您檢查分配是否成功,即malloc是否返回非NULL地址。

確保你在不需要它之後釋放內存:free(entry->name_lower); free(entry->name_caps);

0

它不會丟失什麼。 struct中的指針將保留它們的值,但內容將會改變,最終您將獲得SIGSEGV。

要使char *持續存在,您還需要在堆上分配它。

void bar(foo* entry, const char* str, int delimiter_pos) { 
    char * l = malloc(2); 
    char * c = malloc(2); 
    /* Check l and c for NULLs */ 

    l[0] = str[caps_pos-1]; 
    l[1] = '\0'; 
    c[0] = str[caps_pos+1]; 
    c[1] = '\0'; 

    entry->name_lower = l; 
    entry->name_caps = c; 
} 

請記住,您也應該free()結構成員,當你不再需要它。

1

從評論,分配/複製和分配的起始地址爲lc的存儲新塊的最簡單的方法是繼續使用strdup(從string.h):

void bar(foo* entry, const char* str, int delimiter_pos) { 

    char l[2] = {str[caps_pos-1], '\0'}; // create new string 
    char c[2] = {str[caps_pos+1], '\0'}; 

    entry->name_lower = strdup (l); // assign these strings the foo instance 
    entry->name_caps = strdup (c); 
} 

不要忘記到free當不再需要時分配給entry->name_lowerentry->name_caps的內存。

0

如果您對字符串的長度有限制,則可以使用char數組而不是指針。在你的榜樣,所有的字符串有長度爲1。假設你的字符串不能超過15分鐘,則可以使用char[2]代替char*

struct foo { 
    char name_lower[2]; 
    char name_caps[2]; 
    //.. 
}; 

void bar(foo* entry, const char* str, int delimiter_pos) { 
    entry->name_lower[0] = str[caps_pos-1]; 
    entry->name_lower[1] = '\0'; 
    entry->name_caps[0] = str[caps_pos+1]; 
    entry->name_caps[1] = '\0'; 
} 

歷史註釋:

因爲這是很容易使用,人們習慣了這一點,並強制對字符串長度進行人爲限制,導致緩衝區溢出。如果您的字符串不受限制,請使用動態分配而不是char陣列。