【问题标题】:Is this an acceptable malloc example?这是一个可接受的 malloc 示例吗?
【发布时间】:2012-07-04 14:30:59
【问题描述】:

以下代码是否可接受。也就是说,这是做 malloc 的正确方法吗?

这是我可以为我的情况工作的最少代码。我认为这是“正确的方法”,但我对 C 语言非常陌生,总体上没有太多线索。我阅读了几篇相关的 SO 帖子,但似乎没有一个完全符合这种情况。评论?

#include <stdio.h>

// example of calling a function that creates a dynamically sized array and
// returns it to a caller that doesn't know or care about the size of the array

char* return_char_array(){
     // for the sake of the example, we determined the size to be 100
     char *f=malloc(100*sizeof(char));
     // stick something in the first couple of elements for test purposes
     *f=65;
     *(f+1)=66;
     return f;
}

int main(){
    // we want this function to remain ignorant of the size or other workings 
    // of the array, so, no '[]' or 'malloc'
    char *wipc = return_char_array();
    // well i guess it cares a little, because we assume there are at least 2 elements...
    printf("%c,%c\n",*(wipc),*(wipc+1));
    system("PAUSE");
    return 0;
}

【问题讨论】:

  • 你有什么问题?
  • 如果这是作业添加作业标签
  • '这是完成调用创建并返回动态大小数组的函数的正确方法'?
  • 从某种意义上说,这并不是真正的家庭作业,因为我没有参加课程或类似的课程。
  • 你的评论说no '[]',但是你使用*(wipc+1),和wipc[1]完全一样。

标签: c arrays dynamic


【解决方案1】:

评论?

使用f[0] 代替*ff[1] 代替*(f + 1)wipc 也是如此。不要忘记致电free

【讨论】:

    【解决方案2】:

    我认为在这种情况下还可以。 但记得释放分配的内存:)

    【讨论】:

      【解决方案3】:

      不,这是一个坏主意,没有多大意义。分配内存的代码需要负责释放它,否则您很可能会发生内存泄漏。

      通常你会编写这样的算法:

      // caller.c
      
      #include "stuff.h"  // the code uses the code module "stuff"
      
      void caller (void)
      {
        int* array = malloc(N * sizeof(int));
      
        do_stuff(array, N);
      
        free(array);
      }
      

      _

      // stuff.h
      
      void do_stuff (int* array, int size);
      

      _

      // stuff.c
      
      #include "stuff.h"
      
      void do_stuff (int* array, int size)
      {
        ...
      }
      

      通过这个程序设计,“do_stuff()”不需要关心内存分配,它只是执行它的算法。也不必担心内存泄漏,因为分配和释放是在同一个地方完成的。

      此外,通过这种设计,do_stuff() 可以与静态分配的内存(简单数组)一样正常工作。

      这种设计几乎是 C 中的标准。整个 Windows API 都使用这种设计作为一个例子。

      【讨论】:

      • 我不是反对者,但返回由malloc 获得的对象是不错的风格。事实上,它是malloc 唯一真正的用途之一,除了处理太大而无法可靠地保存在堆栈中的数据。 malloc 的重点是创建动态存储持续时间的对象;在您的使用中,它相当于一个自动存储持续时间的对象,只是它可以大于堆栈中的容量。
      • @R.. 如果您发现自己返回指向分配它的模块之外的动态内存的非常量指针,那么这是一种不好的风格,不仅因为内存泄漏的可能性,还因为它打破了封装和良好的面向对象设计。为什么别人要负责清理你的垃圾?这个答案并不是突然出现的,我在调试糟糕的编写程序以寻找内存泄漏方面有丰富的经验。在 10 种情况下,有 9 种情况是内存泄漏来自糟糕的程序设计。
      • 不,它不会破坏面向对象的设计;对于面向对象的设计来说,绝对必要。面向对象的库将具有 myobject *myobject_create(...);void myobject_destroy(myobject *); 形式的函数
      • @R.. 如果myobject 是不透明(不完整)类型,我会同意。或者,如果它是一个 const 指针。如果不是这两者中的任何一个,那就是糟糕的设计并且会破坏 oo。
      • 不透明与返回分配对象指针的有效性无关;它仅与可能与相关库/程序相关或不相关的其他面向对象原则相关。在 OP 的代码中,标准 C 字符串是要处理的完全合理的对象类型,不需要将其视为不透明的,并且具有动态存储持续时间可能很有用。唯一的错误是 OP 忘记释放它(并且可能忘记记录该函数返回一个新分配的对象)。
      【解决方案4】:

      任何函数不知道它正在使用的数组的大小没有任何好处。评论需要解释。

      【讨论】:

      • 确实,'main' 需要知道 'return_char_array' 创建的东西的大小;我的意思是,“主要”不需要提前知道。它应该让'return_char_array'创建它需要的任何大小的数组,而不是'main'自己做malloc或指定一个固定的数组大小。 (我希望我说得通)。
      • 好的,但这仅适用于这个非常简单的示例。我会这样写 return_char_array 接受一个参数来指定数组中的元素数。
      • 同意。所以该参数将是一个 int 指针,并且该函数仍会像现在一样返回 malloc 的指针,对吗?
      • 只是一个int:char* return_char_array(int elements),它的行为是一样的
      【解决方案5】:

      乍一看,我承认您没有释放()您的分配空间,这很糟糕(内存泄漏)。那是我能看到的唯一真正的“错误”。但是,如果您想以 Code-Review 的形式获得更多见解,您可以将其发布在 Stackexchange 站点“Code-Review”上,因为该站点更多地解决实际问题和错误。

      【讨论】:

        【解决方案6】:

        嗯,这确实是最少的代码。 我宁愿将额外的标记字节放在缓冲区的末尾,并记住在 malloc 时将额外的 2 个字节添加到缓冲区长度

        这 2 个字节保留供内部使用,不应暴露给用户。

        【讨论】:

          【解决方案7】:

          几个厘米,

          1)Pl。进行适当的错误处理。如果 malloc 失败会怎样?

          char *f=malloc(100*sizeof(char))
          if (NULL == f)
          {   
             //Take actions ..Exit with error or return NULL..
          }
          

          2)Pl。避免像 100 这样的硬编码值(可能有 #define MAX 100)

          3)Pl。确保正确释放内存。

          【讨论】:

            猜你喜欢
            • 2017-06-14
            • 1970-01-01
            • 2015-04-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-11-28
            相关资源
            最近更新 更多