2012-01-31 77 views
7

比方說,你有─分配的內存字符數組

struct Person { 
    char *name; 
    int age; 
    int height; 
    int weight; 
}; 

如果你做 -

struct Person *who = malloc(sizeof(struct Person)); 

Ç怎麼會知道多少內存分配爲變量,這個可以容納大量的數據/字符串?我是C新手,對內存分配感到困惑。

+0

不要嘗試編寫多語言源文件。我相信用C++管理內存的慣用方式是[RAII](http://en.wikipedia.org/wiki/RAII)。 – pmg 2012-01-31 14:38:47

+1

不,'name'只是一個指針,它具有不同的大小(通常爲4或8個字節)。一旦你意識到這一點,你明白了。 – 2012-01-31 14:46:42

回答

4

它不知道,你將不得不爲它分配內存。

struct Person *who = malloc(sizeof(struct Person)); 

分配足夠的內存來存儲類型Person的對象。
Person對象內,成員name只佔用一個空間,等於指向char的指針的大小。
上面的malloc只是分配了這麼多的空間,爲了能夠做任何有意義的成員指針,你將不得不分配內存給它。

#define MAX_NAME 124 
who->name = malloc(sizeof(char) * MAX_NAME); 

現在構件name點尺寸124字節的堆上的動態存儲器中,它可以被進一步使用。

此外,使用完成後,您需要明確記住free,否則最終會發生內存泄漏。

free(who->name); 
free(who); 
+4

我假設Q是無效標記'C++',因爲OP說* C怎麼會*和*我是C的新手...... *如果Q是C++,答案與使用'的std :: string'。 – 2012-01-31 14:38:11

+0

我把它標記爲C++,因爲我認爲它們在內存管理方面有相似之處。或者我錯了?我是C新手,但對編程一般來說並不陌生。感謝超級快速的迴應。 – DragonBorn 2012-01-31 14:41:15

+2

@ZiG確實有相似之處(儘管你寧願在'malloc'上使用'new')。但是在C++中,您通常不必mess with任何低級內存管理,例如通過對字符串使用'std :: string',而不是簡單的char數組(或指針),或者使用'std :: vector'來代替自制的動態數組。 – 2012-01-31 14:49:39

-2

我想你也應該需要name屬性

0

它不分配內存。你也必須這樣做。

struct Person *who = malloc(sizeof(struct Person)); 
who->name = malloc(sizeof(char) * 16); /* for a 15+1 character array */ 
0

你有一個指向你的結構中的名字字符數組的指針,即。它將佔用表示內存地址所需的那麼多字節。

如果您想實際使用該字段,則必須爲其分配額外的內存。

0

它將爲name指針分配4個字節,但不會爲「真實」字符串指定空間。如果你嘗試寫在那裏,你會陷入錯誤;你需要malloc(和free)它分開。

使用string(在C++)可以爲您節省一些頭痛

+0

我想它會在64b計算機上分配8B) – Vyktor 2012-01-31 14:33:22

+0

Blah,對:) – 2012-01-31 14:33:52

2

name成員只是一個指針。指針的大小因底層體系結構而異,但現在通常是4或8個字節。

name可以指向的數據(如果稍後分配)應放置在與struct根本不吻合的區域。

在語言級別,struct不知道name成員指向的內存;你必須手動管理。

0

對於指針,結構只是爲指針分配了足夠的內存。您必須爲char *創建內存並將值分配給結構。假設你有char* name地方:

struct Person *who = malloc(sizeof(struct Person)); 
who->name = malloc((strlen(name)+1) * sizeof(char)); 
strcpy(who->name, name) 
+0

可以使用'stdup'來創建'who-> name'。 – 2012-01-31 15:07:57

+0

我認爲你的意思是strdup?如果可用,但它不是ANSI C標準的一部分。此代碼示例應該是有效的ANSI C – 2012-02-01 08:07:44

+0

從未在需要有效的ANSI C的問題中提及它。許多實現包括可以被視覺化的這個例程。 – 2012-02-01 08:43:51

0

指針成員佔用一個字,在我的經驗(在女巫的數據實際上所在的地址),以便大小可能會是16個字節(假定一個字是4個字節)

正如上面的男人所說的,你需要爲* name分開分配內存,將空餘的內存放到你想要的大小的其他地方

3

不要假設存儲器中存儲名稱的指針與存儲名稱數據。假設一個4字節的字大小,可以有以下幾種:

  • char * (4 bytes)
  • int (4 bytes)
  • int (4 bytes)
  • int (4 bytes)
  • ================
  • total: 16 bytes

這是:sizeof(char*) + sizeof(int) + sizeof(int) + sizeof(int)。 C知道大小,因爲你已經告訴它結構定義中元素的大小。

,我認爲你是什麼困惑的是:

char *的內容將是一個存儲位置(例如0x00ffbe532),這是實際的字符串將被保存。不要認爲結構內容是連續的(因爲指針)。事實上,你可以肯定他們不會。

因此,要重申,對於例如struct Person(這只是一個例子,該位置將不會在一個真正的程序相同。)

  • location : [contents]
  • 0x0000 : [0x00ffbe532]
  • 0x0004 : [10]
  • 0x0008 : [3]
  • 0x000C : [25]

  • 0x00ffbe532 : [I am a string\0]

+0

+1的詳細答案。謝謝。 – DragonBorn 2012-01-31 15:06:47

+1

請不要在你的帖子上簽名。 – 2012-01-31 15:27:18

2

它分配內存對於剛剛指針爲char。您需要爲內容分別進行分配。

還有其他的選擇,雖然:

如果您是具有固定大小的最大長度OK,你可以這樣做:

struct Person { 
    char name[PERSON_NAME_MAX_LENGTH+1]; 
    int age; 
    int height; 
    int weight; 
}; 

並分配它作爲你的榜樣。

或者你也可以聲明variable sized struct,但我不會推薦這個,因爲它是棘手的,你不能每結構多個可變大小的數組:

struct Person { 
    int age; 
    int height; 
    int weight; 
    char name[]; /*this must go at the end*/ 
}; 

,然後分配它喜歡:

struct Person *who = malloc(sizeof(struct Person) + sizeof(char)*(name_length+1));