Malloc()为单个结构创建空间,而不是结构数组

时间:2011-06-01 00:33:41

标签: iphone objective-c struct malloc arrays

我整天都在反对这个问题,我会非常感谢任何可以提供帮助的人。

这是交易 - 我正在尝试使用malloc()创建动态C数组。这个数组将保存CGPoint结构,我开始构建并在构建数组后立即分配。这是代码:

CGPoint* tempVertices = malloc(sizeof(CGPoint) * 4);  //defining a collision frame
tempVertices[0] = CGPointMake(37, 46);
tempVertices[1] = CGPointMake(69, 40);
tempVertices[2] = CGPointMake(48, 6);
tempVertices[3] = CGPointMake(17, 10);

//Then I pass the pointer to my array off to a setter...
[self setVertices: tempVertices];

然而,当tempVertices被创建时,似乎我只获得了一个CGPoint的空间:

int test1 = sizeof(CGPoint);        // 8
int test2 = sizeof(tempVertices);   // 4
int test3 = sizeof(*tempVertices);  // 8

当使用XCode调试器单步执行时,它会显示tempVertices是指向CGPoint的指针。当我设置tempVertices[0]时,CGPoint指向的tempVertices接收该值,这反映在调试器中。我的其他3个插槽去了哪里? tempVertices似乎指向单CGPoint而不是数组。我想要阵列。

关于我做错的任何想法?我知道还有其他方法可以使用C ++或其他对象来解决这个问题,但我想尽可能坚持使用C.

提前致谢!


更新:

要回答zpasternack,setVertices:是一个自定义编写的setter。而且我不知道它是如何/是否知道传入阵列有多大。我试图更好地理解直接C的东西,所以关于传递动态C数组作为参数的正确方法的见解/解释非常受欢迎。这是setter的样子:

- (void) setVertices:(CGPoint*) val {
    _vertices = val;    //_vertices is a member variable of the type CGPoint* 
    //...calculate a centroid, other stuff...
}

如果需要,我可以将我的CGPoints包装在NSValue对象中并改为使用NSArray,但我确实想知道在纯粹的C中执行它的正确方法。

感谢所有评论过的人 - 你们很棒:)

4 个答案:

答案 0 :(得分:4)

在你的32位机器上,你得到了你所期望的。 sizeof(tempVertices)是指针的大小,而sizeof(* tempVerices)给出了CGPint的大小(可能是两个整数)。您无法使用sizeof()获取已分配数组的大小。该值仅在run-rime中已知,而sizeof()是编译时运算符。

答案 1 :(得分:1)

malloc为4个GCPoint结构分配足够的空间,并返回指向已分配空间的指针。

第一个是tempVertices + 0.这是tempVertices [0]。

第二个是tempVertices + 1.这是tempVertices [1]。

第三个是tempVertices + 2.这是tempVertices [2]。

第四个是tempVertices + 3.这是tempVertices [3]。

答案 2 :(得分:1)

好的,在你编辑之后,我想我知道发生了什么。正如您所写的那样,该代码应该可以正常工作。 Xcode不会向您显示任何这些CGPoints的值,因为它不知道它是一个数组,只是一个指向单个CGPoint的指针。但它就在那里。在致电setVertices:后立即设置断点。在gdb提示符下,打印其中一些值。

(gdb) print _vertices[1]
$2 = {
  x = 69, 
  y = 40
}
(gdb) print _vertices[3]
$3 = {
  x = 17, 
  y = 10
}

正确,看?

这并不是说这里没有问题。首先,setVertices:正在泄露那段记忆。你正在为tempVertices分配内存,保留指针,但不能在任何地方释放它。下次拨打setVertices:时,您将发生泄密。

更大的问题是没有人知道该阵列中有多少CGPoints,除了为其分配内存的代码。它总是4个CGPoints吗?如果有人访问_vertices[5]_vertices[27]会怎样?糟糕的事情,如果你没有为他们分配那么多的空间。

是否要求这是一个普通的C数组?比如,这些要点会被传递给OpenGL或cocos2d还是什么?如果没有,您可以考虑使用某种类型的数组。因为这些不是您存储的NSObject派生对象,所以不能使用NSArray。如果您不介意在Buncha C ++中拖动,可以使用std::vector。我可能不会这样做。

如果您坚持使用C数组,那么您应该做一些工作来尝试使界面不易出错。就像我之前提到的,你需要跟踪数组的大小。也许你可以为setVertices添加一个参数:表示数组所拥有的CGPoints的数量。然后,访问_vertices的代码的其他部分可以检查以确保它们不会离开数组的末尾。并且,就像我之前提到的那样,确保在重新分配指针之前释放内存。

用指针搞乱充满了危险。仔细踩,那里有龙。

答案 3 :(得分:0)

我不会使用sizeof()来确定在运行时分配的数组的大小。

您是否确实在将新CGPoint个对象分配到阵列时遇到了问题? CGPointMake()是否执行自己的任何分配?