返回malloc指针

时间:2011-03-31 00:51:00

标签: c struct malloc

这里非常基本的问题,我对C中记忆的传递有点不确定。

如果我有以下

CGPoint* tileForCoordinates (CGPoint position, short width, short height)
{   
   CGPoint *tileCoordinate = (CGPoint*)malloc(sizeof(CGPoint));
   tileCoordinate->xTile = (position.xPosition / width);
   tileCoordinate->yTile = (position.yPosition / height);

   return tileCoordinate;
}

我想在另一个源文件中调用它或者其他什么,我会在上面声明一个指针并返回它吗?如果是这样,当我打电话来自其他类别时,例如

CGPoint *currentTilePosition = tileForCoordinates(curPosition, 50, 50);

malloc返回的指针会发生什么?它应该被释放还是故事? :)

5 个答案:

答案 0 :(得分:4)

你可以将tileCoordinate作为参数传递给函数调用吗?这样,调用者就会发现更容易记住malloc / calloc和free。

答案 1 :(得分:4)

回答“malloc()返回的指针发生了什么?”

malloc()声明的指针将是当前正在执行的函数的堆栈帧中的值。当堆栈帧(以及因此*tileCoordinate)在函数返回时超出范围时,该指针将不再存在。

但是,因为您将指针值返回给调用函数,它现在存在于当前堆栈帧中(返回后)。该值由变量*currentTilePosition引用。

malloc()分配的内存是一个完全不同的故事;堆上存在动态分配的内存。您应释放在执行分配的同一实现中分配的任何内存。这意味着一旦您使用free(),就会在currentTilePosition上调用{{1}},通常是在同一个文件中。

答案 2 :(得分:3)

要遵循的非常基本的规则是,如果你返回一个* malloc * ed指针,或者给用户一个函数将指针传递回来进行释放,或者记录你* malloc * ed它并且它们应该释放它。

我已经看到了各种各样的解决方案(包括完整的内存管理抽象),我个人更喜欢API指定的免费方法,因为当需要释放对象并且它提供API时,它很清楚该怎么做最后一次尝试进行任何额外的清理工作。

答案 3 :(得分:3)

调用者需要free您的函数指针malloc

但是,如果将tileForCoordinates函数打包到动态库中,则还应提供一个用于释放内存的附带函数,而不是让调用者执行此操作。这是因为调用者可能以与库不同的方式链接到C运行时。例如,如果您的库静态链接到C运行时,而调用者动态链接到它,反之亦然,让调用者释放内存将导致崩溃。在这种情况下,您可以提供类似于以下的功能:

void freeTileCoordinates( CGPoint **tileCoordinate )
{
  // Also add additional checks for NULL pointer
  free( *tileCoordinate );
  *tileCoordinate = NULL;
}

使用示例:

CGPoint *point = tileForCoordinates( ... );

// use point
...

// now free it
freeTileCoordinates( &point );

答案 4 :(得分:1)

作为一项规则,您malloc所需要的所有内容free。作为另一个规则,如果您的api进行了分配,那么您的api也应该进行解除分配,因为在未来的某个时间点,您可能会改变基础机制。此外,在Windows中,如果内存是由DLL分配的,则必须使用相同的DLL释放内存或发生崩溃的事情。

因此,一般来说,模式看起来像这样:

MyType* foo = myapi_dosomething(x,y,z);
if (!foo) die("No Foo!");
use_object(foo);
myapi_free(foo);
foo=NULL; // just in case