【问题标题】:Allocation of memory for char arraychar数组的内存分配
【发布时间】:2012-01-31 14:29:26
【问题描述】:

假设你有-

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

如果你这样做-

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

C 如何知道为 name 变量分配多少内存,因为它可以容纳大量数据/字符串?我是 C 新手,对内存分配感到困惑。

【问题讨论】:

  • 不要尝试编写多语言源文件。我相信在 C++ 中管理内存的惯用方法是使用 RAII
  • 不,name 只是一个指针,它具有不同的大小(通常为 4 或 8 个字节)。一旦你意识到这一点,你就明白了。

标签: c memory-management


【解决方案1】:

它不会知道,你必须为它单独分配内存。

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); 

【讨论】:

  • 我假设 Q 被无效标记为 C++,因为 OP 说 C....我是 C...的新手 i> 如果 Q 是 C++,则答案与使用 std::string 非常相似。
  • 我将其标记为 C++,因为我相信它们在内存管理方面具有相似性。还是我错了?我是 C 的新手,但一般来说对编程并不陌生。感谢您的超级快速响应。
  • @ZiG 确实有相似之处(尽管您更愿意使用new 而不是malloc)。但是在 C++ 中,您通常不必搞乱任何低级内存管理,例如对字符串使用std::string,而不是普通的char数组(或指针),或者使用std::vector而不是自制的动态数组。
  • @Zig 如果您觉得接受它很好,请不要忘记为答案 +1。
  • You will have to allocate memory for it separately. 错误。这是您为其分配内存的 pointeename的记忆力很好。
【解决方案2】:

不要假设存储 name 指针的内存与存储 name 数据的内存相同。假设字长为 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]

【讨论】:

  • 请不要在您的帖子上签名。
【解决方案3】:

name 成员只是一个指针。指针的大小因底层架构而异,但现在通常为 4 或 8 个字节。

name 可以指向的数据(如果稍后分配)应放置在与struct 完全不重合的区域中。

在语言级别,structname 成员指向的内存一无所知;您必须手动管理。

【讨论】:

    【解决方案4】:

    它只为指向 char 的指针分配内存。您需要对内容进行单独分配。

    还有其他选择:

    如果您可以接受固定大小的最大长度,您可以这样做:

    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));
    

    【讨论】:

      【解决方案5】:

      它将为name 指针分配4 个字节,但不为“真实”字符串分配空间。如果你尝试在那里写,你会出现段错误;你需要分别malloc(和free)。

      使用string(在 C++ 中)可以省去一些麻烦

      【讨论】:

      • 我猜它会在 64b 机器上分配 8B :)
      【解决方案6】:

      对于指针,结构被分配了足够的内存供指针使用。您必须为 char* 创建内存并将值分配给结构。假设你在某处有char* name

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

      【讨论】:

      • 只能使用stdup 创建who->name
      • 我猜你的意思是strdup?如果它可用,但它不是 ANSI C 标准的一部分,你可以。此代码示例应该是有效的 ANSI C
      • 从未在需要有效 ANSI C 的问题中提到它。许多实现都包含这个可以优化的例程。
      • 没有指定 C 的版本,所以我选择了一个合适的标准。
      【解决方案7】:

      它没有。你也必须这样做。

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

      【讨论】:

        【解决方案8】:

        您的结构中有一个指向名称字符数组的指针,即。它将消耗表示内存地址所需的那么多字节。

        如果要实际使用该字段,则必须为其分配额外的内存。

        【讨论】:

          【解决方案9】:

          根据我的经验,指针成员占用一个字(数据实际驻留的地址),所以大小可能是 16 个字节(假设一个字是 4 个字节)

          正如上面所说,您需要为 *name 单独分配内存,女巫将在其他地方释放内存以达到您想要的大小

          【讨论】:

            【解决方案10】:

            我认为您还应该为 name 属性分配内存

            【讨论】:

              猜你喜欢
              • 2023-03-15
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-06-08
              • 2019-11-12
              • 2011-02-23
              • 1970-01-01
              相关资源
              最近更新 更多