c - 使用malloc和直接初始化到堆栈在内存空间方面的区别

标签 c memory struct

我一直在阅读“Learn C the Hard Way”,我遇到了一个有趣的问题,我希望有人能详细解释它。基本练习是使用包含示例 Person 结构的结构。在第一种情况下,我有一个类似构造函数的方法(如果有人不介意在旁边解释的话,我不完全明白为什么教程会这样做:D)以及这样的结构:

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

struct Person *Person_create(char *name, int age, int height, int weight) 
{
  struct Person *who = malloc(sizeof(struct Person)); 
  assert(who != NULL);

  who->name = strdup(name);
  who->age = age; 
  who->height = height;
  who->weight = weight;
}

与其余代码一起,运行得很好,但是当我打印指向这些结构的指针的内存位置时,如下所示:

int main(int argc, char* argv[]) {
     struct Person *joe = Person_create("joe alex", 12, 80, 100);
     struct Person *joe = Person_create("frank blank", 20, 72, 140);
}

它们的内存值的差异总是正好 40。相比之下,结构构造函数的实现如下:

 struct Person{//is the same as above};

 struct Person Person_create (char* name, int age, int height, int weight) {
  struct Person newPerson;
  newPerson.name = name; //and so on

  return newPerson
 }

当我打印出 joe 和 Frank 的内存位置(使用与上面相同的值进行初始化)时,通过上面的实现,它们的内存位置的差异似乎始终是 20。

我研究了一些汇编,我知道编译器根据结构的数据类型分配内存块,所以我在想..在这两种实现中,一个 char 数组有很多字符,所以 n 个字符 * 1 = 字符空间,然后我有 3 个整数,所以 3*4 = 12; 12 + 9 (Joe Alex\0 对吗?) = 21..我可能把\0 弄错了,所以它等于 20 或其他东西,但无论我的结构的具体内存大小如何,我更感兴趣的是为什么这两个不同的实现会导致不同的内存大小(根据我的理解,双倍的内存成本是相当大的数量)。

最佳答案

在第一种情况下,进行了 4 次动态分配:两个使用 strdup 的名称字符串,以及使用 malloc 的 2 个 Person 结构。结构地址之间的差异告诉您大致分配了多少内存,包括第一个结构和第二个结构之前[*]

在第二种情况下,没有进行动态分配,但我想您已经在堆栈上创建了两个 Person 对象:

struct Person joe = Person_create("joe alex", 12, 80, 100);
struct Person frank = Person_create("frank blank", 20, 72, 140);

它们的地址之间的差异可以告诉您第一个地址大致占用了多少内存[*]。

由于您尚未复制字符串,因此您几乎需要使用字符串文字作为名称,或者与 Person 结构分开管理其内存。字符串数据不是struct Person的一部分——永远不会。 newPerson.name = name 仅存储指针,而不是字符串数据。

一旦您开始从文件或终端读取名称,这就会变得很麻烦:无论如何,您都必须动态分配它们,因此您不会节省任何内存,但您必须编写更多代码。该练习可能包括一个 Person_Destroy 函数,它 free 是名称,因此 struct Person 的用户不必单独担心这个问题.

[*] 除了实现不需要一个接一个地分配这些东西之外,所以你的方法通常不起作用。它恰好在这种情况下给出的结果与分配按照您进行分配的顺序放置的理论一致。

关于c - 使用malloc和直接初始化到堆栈在内存空间方面的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10734439/

相关文章:

c++ - 全关联缓存

unix - 我可以决定在 LSF 队列中分配多少内存吗

c - 改进了在结构指针内为结构双指针动态分配内存的方法

c - C中结构内数组的初始化

c - 隐藏结构上的单个项目

c - 如何使嵌入在关于对话框中的 url 显示为超链接? (资源脚本.rc)

c - 使用 Windows 套接字的 WriteFile 返回无效参数错误

C 到 Cross Compiler 的 Assembly MIPS(需要解释 $sp, $fp)

c++ - C++/ActiveX用malloc,memcpy,free替换了realloc。功能和性能测试

c - 用零值初始化结构数组