代码之家  ›  专栏  ›  技术社区  ›  RWS

如何确保调用者传递malloc'd指针?

  •  6
  • RWS  · 技术社区  · 15 年前

    我有一个函数,它将作为参数的指针重新分配到一个新的大小。现在,问题是-根据手册页- realloc 需要已由返回的指针 malloc calloc

    如何确保调用者传递的指针满足这些要求? 似乎没有内置的C机制(比如类型限定符之类的)来实现这一点。

    提前谢谢。

    一个解决办法显然是解决malloc 在里面 函数。问题是调用者没有“看到”分配。因此,我需要在文档中明确地说,他必须释放指针。这比期望它们提供malloc'd指针更糟糕(这意味着调用者必须释放它)。

    11 回复  |  直到 15 年前
        1
  •  10
  •   S.Lott    15 年前

    如何确保调用者传递的指针满足这些要求?

    文档。

    如果编写调用者的人拒绝遵循API,事情就会崩溃。他们拒绝按你的规矩办事,结果事情就一团糟了。他们期望什么?

        2
  •  4
  •   user395760 user395760    15 年前

    归根结底,C中的指针只不过是一个机器字,它可能指向进程内存中的大量数据,也可能不指向,这些数据可能由malloc分配,也可能不由malloc分配。任何指针上都没有此类信息。

        3
  •  2
  •   Michael F    15 年前

    无法确定指针所指向的区域是否已被删除 [m|c]alloc(); 'd。您只能定义您的API,并希望您的API用户遵循它。

    realloc(NULL, size); 如果你受这个约束的话。

    关于你问题的更多信息会很好。

        4
  •  2
  •   Nyan    15 年前

    一种可能的方法。 抽象的。

    foo.c
    #include "foo.h"
    struct foo{
       ...
    } ;
    
    foo *newFoo(...)          
    void resize(foo *f)      
    
    foo.h
    
    struct foo;
    typedef struct foo;
    
    caller.c
    
    foo *myfoo;
    myfoo = newFoo(..)
    resize(myfoo);
    
        5
  •  2
  •   asr    15 年前

    用户首先应该如何获得这个malloc'ed指针?这不可能是由API中的另一个函数获得的吗?否则对我来说,这听起来像样板代码,在调用函数之前必须用malloc分配一块内存。

    在你的情况下我会试试的。让调用者通过我提供的函数获得一个有效的指针,并通过另一个函数释放它。更妙的是,将其全部包裹在一个不透明的结构中。

    my_param_type my_param = init_param(....);
    ...
    my_function_that_wants_malloc(.....,my_param);
    ...
    free_param(my_param);
    

    在你的API中这有意义吗?

    有了自己的类型,即使是最蹩脚的用户也会很清楚,他必须通过预期的init\u param()函数获得它。

        6
  •  0
  •   JeremyP    15 年前

        7
  •  0
  •   John Bode    15 年前

    如果只有指针值,则没有(标准)方法来确定该指针值是否由 malloc() . 如果您对动态内存分配在您的平台上的工作方式有很深的了解,那么您可以根据指针值进行有根据的猜测,但即使这样也不能保证您看到的东西实际上是来自 malloc() 与此相对应的值偏移量(例如。, *ptr = malloc(10); foo(&ptr[5]); ).

    一个策略,可能值得或不值得的努力(输入法,它不是)是隐藏 , realloc() ,和 free() 在某种内存管理器后面,它跟踪分配的指针和大小。而不是打电话 重新分配() ,则代码将调用内存管理器中的resize函数,如果传递给它的指针不在托管指针列表中,该函数将返回错误代码。

        8
  •  0
  •   Brandon Horsley    15 年前

    请注意,如果realloc失败,它将返回一个空指针,但原始malloc的内存保持不变,这是内存泄漏的常见来源。

        9
  •  0
  •   bta    15 年前

    typedef void* myPointerType;
    

    编写一个分配函数(可以是一个简单的包装器) malloc

    myPointerType myAllocateFunction (size_t size) {
        return (myPointerType)(malloc(size));
    }
    

    您还需要创建一个匹配的“free”函数。

    realloc )拿一个 myPointerType 对象作为参数而不是泛型指针。你可以把它扔回原处 void* 与…一起使用 . 为了避免这种情况,用户必须手动抛出一个非- 马洛克 指向 我的指针类型 ,但您可以在文档中指定 是不允许的(所以如果他们这样做,他们的应用程序崩溃,这是因为他们误用了API)。

    有更强大的方法,你可以执行这一点,但我不确定是否值得的麻烦。你不可能完全证明一个API是傻瓜(你会惊讶于现在傻瓜的能力有多强)。无论最终实现什么,确保正确使用API的最佳方法是提供清晰、全面的文档。

    对不起,你只能靠自己了。

        10
  •  0
  •   supercat    15 年前

    如果您正在寻找编译时检查,您唯一真正能做的就是声明一些新类型,这些类型由“已批准”的分配调用返回。我建议如下:

    typedef struct MEM_INFO {void *ptr; int allocsize; struct *privateMemInfo priv;} ALLOCMEM[0];
    

      ALLOCMEM foo = {0};
      if (reallocate(foo,12345) >= 0) /* It worked */
    
        11
  •  0
  •   el.pescado - нет войне    15 年前

    因此,我需要明确地说 指针。那甚至比你想的更糟 希望他们提供一个 指针(这意味着 呼叫方必须释放它)。

    在C库中,这是一种常见的做法: