簡體   English   中英

返回malloc指針

[英]Returning a malloc pointer

這里非常基本的問題,我對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返回的指針會發生什么? 它應該被釋放還是故事? :)

回答“malloc()返回的指針發生了什么?”

malloc()聲明的指針將是當前正在執行的函數的堆棧幀中的值。 當堆棧幀(以及因此*tileCoordinate )在函數返回時超出范圍時,該指針將不再存在。

但是,因為您將指針值返回給調用函數,它現在存在於當前堆棧幀中(返回后)。 該值由變量*currentTilePosition引用。

通過所分配的存儲器 malloc()是一個完全不同的故事; 堆上存在動態分配的內存。 您應釋放在執行分配的同一實現中分配的任何內存。 這意味着一旦你完成使用它就會在currentTilePosition上調用free() ,通常是在同一個文件中。

你可以將tileCoordinate作為參數傳遞給函數調用嗎? 這樣,調用者就會發現更容易記住malloc / calloc和free。

要遵循的非常基本的規則是,如果你返回一個* malloc * ed指針,或者給用戶一個函數將指針傳遞回來以便釋放或者記錄你* malloc * ed它並且它們應該釋放它。

我已經看到了各種各樣的解決方案(包括完整的內存管理抽象),我個人更喜歡API指定的免費方法,因為它很清楚當釋放對象時它該做什么,它給了API最后一次嘗試做任何額外的清理工作。

調用者需要free您的函數malloc ed指針。

但是,如果將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 );

作為一項規則,一切你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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM