2012-01-31 76 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));