`pixel(* copy)[rows] = malloc(cols * sizeof(* copy))需要多少次调用free()?

时间:2016-01-04 20:37:09

标签: c arrays malloc free c99

我已经看到了在C99中使用以下表达式分配2D数组的各种建议:

int (*array)[cols] = malloc(rows * sizeof *array);

我想知道三件事:

  1. 是否在堆上分配了整个结构?或者这实际上是一堆指针(在堆栈上)指向堆上的数组..?

  2. 分配的内存是否完全连续?

  3. 是否只需要一次调用free(array)来释放整个2D结构?我在某个地方看过这个 - 不记得在哪里 - 它似乎对我有用,但我想了解原因。

2 个答案:

答案 0 :(得分:8)

  

(1)整个结构是否在堆上分配?或者这实际上是一堆指针(在堆栈上)指向堆上的数组..?

整个结构(malloc分配的所有内容)都在堆上。

  

(2)分配的内存是否完全连续?

是的,override func viewDidLoad() { super.viewDidLoad() getJSON { (usdPrice) -> Void in // do something with usdPrice print(usdPrice) } } func getJSON(completion: (Double) -> Void) { let url = NSURL(string: baseURL) let request = NSURLRequest(URL: url!) let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration()) let task = session.dataTaskWithRequest(request) { (data, response, error) -> Void in if error == nil{ let swiftyJSON = JSON(data: data!) let usdPrice = swiftyJSON["bpi"]["USD"]["rate"].doubleValue completion(usdPrice) } else { print("There was an error!") } } 分配一个连续的存储区域。

  

(3)是否只需要一个调用free(array)来释放整个2D结构?我在某个地方看过这个 - 记不清楚 - 它似乎对我有用,但我想了解原因。

是的,这是真的。至于为什么,它为什么会以其他方式?您使用malloc分配单个存储区域,malloc用于取消分配先前free返回的单个存储区域。

我怀疑你对声明类​​型感到困惑,尽管你没有提到它:

malloc

这意味着int (*array)[cols] 变量成为单个指针(它本身在堆栈上分配)到一个带有array元素的int数组(在其上分配)堆由于使用cols)。将此与更常见的比较:

malloc

...而是声明一个指针的一维数组(其中数组本身将在堆栈上)。您可以使用后者创建一个指向数组的数组,方法是在每个元素中存储指向一系列数组的指针(您确实必须单独分配和释放这些数组!)。这种结构可以与2D数组类似的方式使用,但实际上不是一回事。

还要记住C中的指针始终指向数组。因此,即使第一个声明声明了一个指向一维数组的指针,它也可以用来指向数组这样的数组,即你想要的二维数组。实际上,int *array[cols] 调用为这样的数组分配了存储空间:

malloc

这里,malloc(rows * sizeof *array); 是具有sizeof *array元素的(单个)1D数组的大小(以字节为单位)。当乘以行数时,它会产生大小为cols×rows的二维数组的存储要求。

答案 1 :(得分:2)

C不进行隐藏内存分配。问题中的类型可以用作真正的2D数组。实际上它是指向cols"的数组[int]的指针。

OTOH,类似int *array[cols](注意缺少的括号)不是2D数组,而是指向int"的指针数组。然而,即使在这里,您也必须明确malloc数组和每一行!

对于每个malloc,您需要相应的free

请注意,C标准不需要堆,堆栈或任何其他特定的管理结构。这留给实施。但是,大多数托管环境(即完整大小的运行时)使用类似堆的东西。

请记住检查malloc的结果并正确处理分配失败。