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



我整天都在思考这个问题,我非常感谢任何能帮忙的人。

事情是这样的——我正在尝试使用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]时,tempVertices指向的CGPoint将接收该值,该值将反映在调试器中。我的其他3个插槽都去哪儿了?CCD_ 6似乎指向单个CCD_。我想要数组。

你知道我做错了什么吗?我知道使用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代替,但我确实想知道在普通的ol‘C.中实现这一点的正确方法

感谢所有发表评论的人——你们太棒了:)

在您的32位机器上,您得到的正是您所期望的。sizeof(tempVertices)是指针的大小,而sizeof(*tempVerices)提供CGPint的大小(可能是两个int)。使用sizeof()无法获取已分配数组的大小。该值只有在运行时才知道,sizeof()是一个编译时运算符。

好吧,在你编辑之后,我想我看到了发生了什么。这段代码,就像你写的一样,应该可以正常工作。Xcode不会向你显示任何一个CGPoint的值,因为它不知道它是一个数组,只是一个指向单个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的代码的其他部分可以对此进行检查,以确保它们不会偏离数组的末尾。而且,正如我之前提到的,在重新分配指针之前,请确保释放内存。

信手拈来充满危险。小心踩,那里有龙。

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

第一个是在tempVertices+0处。这是tempVertices[0]。

第二个是在tempVertices+1处。这是tempVertices[1]。

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

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

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

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

最新更新