【问题标题】:What is malloc doing in this code?malloc 在这段代码中做了什么?
【发布时间】:2009-07-31 16:02:06
【问题描述】:

你能解释一下下面的代码吗?

str = (char *) malloc (sizeof(char) * (num+1));
  1. malloc 在这里做什么?
  2. 为什么使用num + 1

【问题讨论】:

  • 所有用 malloc 分配的内存必须通过调用 free 来返回。对于每个 malloc 调用,您必须有一个对应的 free 调用。
  • 无需转换为 char*。也不需要指定 sizeof(char),因为 sizeof(char)==1。
  • 在 C++ 中需要转换为 char *,而不是在 C 中。
  • 有理由不这样做,它会抑制一个潜在的警告,即在调用点没有可见的 malloc 声明。
  • @onebyone:当然,除了“不要在 C++ 中使用 malloc”。 ;)

标签: c++ c malloc


【解决方案1】:

malloc 是一个函数 that allocates a chunk of memory on the heap 并返回一个 pointer 给它。它类似于许多语言中的new 运算符。在这种情况下,它创建的内存块可以存在任意长度并具有任意大小。这本身就是相当深入的东西,有点难以解释,需要一个单独的问题。

num + 1 补偿字符串末尾的 null terminator。字符串通常需要知道它们有多长,而 C 的传统是在字符串的末尾为额外的字符分配空间,该字符始终是特殊字符 \0。这允许处理字符串的函数自动确定字符串的大小。例如,如果你想对字符串的每个字符做一些事情而不知道字符串有多长,你可以这样做:

const char *ptr = str;
while (*ptr != '\0') {
    process(*ptr);
    ptr++;
}

【讨论】:

    【解决方案2】:

    malloc 用于内存分配。 num + 1 是允许空终止符 - \0

    【讨论】:

      【解决方案3】:

      序言:我不敢相信!当我学习 C 基础知识时(不是双关语),我对这种表达方式感到困惑。这就是为什么我会在“解析代码”部分中详细介绍。

      解析代码

      第一个问题是解析代码

      欢迎来到暮光之城

      str = (char *) malloc (sizeof(char) * (num+1));
      

      在使用 C/C++ 时,解析这种表达式是强制性的,所以我们将把它分解成它的组件。我们在这里看到的第一件事是这样的:

      variable = (expression) function (expression) ;
      

      我第一次看到它时,我只是“嘿,我不敢相信有一种编程语言可以通过将函数的参数放在函数调用的左侧和右侧来调用函数!”。

      解析这行代码?

      事实上,这一行应该读成这样:

      variable = function_a (function_b (expression)) ;
      

      在哪里:

      expression is sizeof(char) * (num+1)
      function_b is malloc
      function_a is a cast operator
      

      C 类型转换运算符有点不自然

      正如在别处已经解释过的,C 风格的演员表操作符更像

      (function_a) expression
      

      比起来更自然

      function_a(expression)
      

      这解释了整行代码的奇怪之处。

      C++ 有更容易理解的东西吗?

      请注意,在 C++ 中,您可以使用这两种表示法,但您应该使用 static_cast、const_cast、reinterpret_cast 或 dynamic_cast 而不是上述表示法。使用 C++ 转换,上面的代码行将是:

      str = static_cast<char *> ( malloc (sizeof(char) * (num+1))  ) ;
      

      我的 sizeof 比你的大

      sizeof 是一个运算符。您可以将其视为处理类型的函数。 您将类型作为参数传递,它将以字节为单位为您提供其大小。

      所以,如果你写:

      size_t i = sizeof(char) ;
      size_t j = sizeof(int) ;
      

      您可能(在 32 位 Linux 上)i 的值为 1,j 的值为 4。 它在 malloc 中的使用就像是说“我想要足够的空间来放置 25 辆 4 米长的汽车”而不是“我想要至少 100 米”。

      关于 Malloc 的一些东西

      Malloc的参数是一个size_t,也就是一个无符号整数。你给它以字节为单位的大小,如果成功,它会返回分配内存的地址,该地址足够大,可以用作数组。例如:

      int * p = (int *) malloc (25 * sizeof(int)) ;
      

      然后 p 指向一个内存,您可以在其中并排放置 25 个整数,就好像在一个索引从零到大小为一的数组中一样。例如:

      p[0] = 42 ;  // Ok, because it's the 1st item of the array
      p[24] = 42 ; // Ok, because it's the 25th item of the array
      p[25] = 42 ; // CORRUPTION ERROR, because you are trying to
                   // use the 26th item of a 25 items array !
      

      注意:你也有指针算术,但这超出了问题的范围。

      num + 1?

      C 风格的字符串与其他语言的字符串有些不同。 字符串的每个字符都可以是任何值,但不能为零。 因为零(也称为 \0)标志着 c 字符串的结尾。

      换一种说法:你永远不知道 c 字符串的大小,但是通过搜索 \0 字符,你可以知道它的结束位置(顺便说一句,这是缓冲区溢出和堆栈损坏的原因之一)。

      例如,字符串“Hello”似乎有 5 个字符:

      "Hello" seems to be an array containing 'H', 'e', 'l', 'l' and 'o'.
      

      但实际上,它有 6 个字符,最后一个是字符 ZERO,使用转义字符 \0 表示。因此:

      "Hello" is an array containing 'H', 'e', 'l', 'l', 'o' and 0.
      

      这说明当您想为“num”个字符的字符串分配足够的空间时,您应该分配“num + 1”个字符。

      【讨论】:

      • 很好的解释!
      【解决方案4】:

      ma​​lloc 分配内存。

      num+1 因为 num 是字符串中的字符数,+1 表示空终止符

      【讨论】:

        【解决方案5】:

        在这种情况下,Malloc 分配了 num+1 倍 sizeof(char) 字节。当您要分配元素数组时,这是标准做法。 sizeof(char) 中的 char 通常替换为正在分配的数组类型。

        严格来说,在这个例子中虽然 sizeof(char) 不是必需的。 C 标准保证它的大小为 1,因此只需乘以 1。

        【讨论】:

          【解决方案6】:

          malloc 在堆上分配一个 char 数组(在本例中)。

          数组将是 num+1 长,但它可以容纳的最长字符串是 'num' 长,因为 C 中的字符串需要一个结束的空字节。

          【讨论】:

            【解决方案7】:

            Malloc 分配内存,在本例中为长度为 num 的字符串 str。 (char *) 是 str 的类型 sizeof(char) 是每个字符所需的字节数。 +1 用于字符串中的尾随空字符,通常为零。

            【讨论】:

              【解决方案8】:

              Malloc 是一个分配内存的调用。

              上面的代码将为 num + 1 个字符分配空间。可能有一个包含num个字符的字符串,并且代码的作者为空终止符添加了空间。

              调用 str 后将指向已分配内存块的开始。

              【讨论】:

                【解决方案9】:

                这段代码尝试分配一块可以容纳 num + 1 个 char 类型值的内存。因此,如果聊天等于 1 个字节且 num 为 10,它将尝试分配 11 个字节的内存并返回指向该内存的指针。

                +1 很可能被使用,因为程序员想要存储一个由 num 个字符组成的字符串(字符数组)并且需要一个额外的 char 来存储终止 '\0'(空)字符。在 C/C++ 中。按照惯例,字符字符串以空字符结尾。

                【讨论】:

                  【解决方案10】:

                  malloc 从堆中分配内存并返回一个指向它的指针。当您不知道编译时需要多少内存时,它很有用。

                  至于为什么(num+1),这真的取决于代码在做什么......也许num是字符串中的字符数,而+1是最后的NUL终止符字节。不过,我不知道 sizeof(char) 在这种情况下的用途。

                  【讨论】:

                    【解决方案11】:
                    sizeof(char)
                    

                    是安全的。不应假定每个字符只有一个字节。

                    如果你不知道 malloc 做什么,我的问题是你在做什么编程?

                    man malloc
                    

                    在 Linux 系统上。在 Windows 上。谁知道?大概 17 次鼠标点击。

                    【讨论】:

                    • “不应假定每个字符一个字节”。为什么不? sizeof(char) == 1 由标准保证。 C++ 没有其他字节的概念。
                    • 因为将来可能会改变?许多旧代码假定指针和整数的大小可以互换。见鬼,一些旧代码假定链接器假定内部符号最多为 6 个字符。
                    猜你喜欢
                    • 2016-02-17
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2012-09-04
                    • 2017-07-25
                    相关资源
                    最近更新 更多