我在一个struct中有一个C-array的C-array。我需要在添加另一个CGPoint时替换此数组。我发誓我正在做这件事,似乎工作很好几次,但最终我会得到一个EXC_BAD_ACCESS
。我错过了什么?
这是结构,我已经截断它以删除许多不属于的项目。
typedef struct{
CGPoint **focalPoints;
NSUInteger focalPointCount;
CGRect boundingRect;
}FocalPoints;
以下是我如何初始化它:
CGPoint *fPoints = (CGPoint *)malloc(sizeof(CGPoint));
FocalPoints focalInfo = {&fPoints, 0, rect};
请注意focalInfo
通过引用传递给另一个函数,如:anotherFunction(&focalInfo)
。
现在这里是用新数组替换Points数组的函数:
void AddFocalPoint (CGPoint focalPoint, FocalPoints *focal){
if (focalPoint.x == CGFLOAT_MAX) return;
if (!CGRectContainsPoint(focal->boundingRect, focalPoint)) return;
int origCount = focal->focalPointCount;
int newCount = origCount + 1;
CGPoint *newPoints = (CGPoint *) malloc((newCount) * sizeof(CGPoint));
for (int i = 0; i < newCount; i++)
newPoints[i] = (i < origCount) ? *focal->focalPoints[i] : focalPoint; //error occurs here
free(*focal->focalPoints);
*focal->focalPoints = newPoints;
focal->focalPointCount = newCount;
}
第8行上面的代码中出现了EXC_BAD_ACCESS错误:newPoints[i] = (i < origCount) ? *focal->focalPoints[i] : focalPoint;
。那究竟是我做错了什么?
答案 0 :(得分:3)
这有点远,但可能在*focal->focalPoints[i]
中存在运营商优先权问题。您是否尝试根据您要实现的目标添加括号?
答案 1 :(得分:2)
我相信问题来自于GCPoint *fPoints
分配为&fPoints
的地址评估为该地址...一旦该函数退出就不再有效。
(指向的数据已被malloc
分配。)
答案 2 :(得分:1)
除了我在评论中提出的使用链接列表/ NSMutableArray
的建议外,我的另一个建议是您使用realloc()
而不是经常使用malloc()
,复制方式手,然后free()
旧的分配。
void * realloc(void *ptr, size_t size);
realloc()
函数尝试将ptr
指向的分配大小更改为size
,并返回ptr
。如果没有足够的空间来扩大ptr
指向的内存分配,realloc()
会创建一个新的分配,复制尽可能多的ptr
所指向的旧数据。新分配,释放旧分配,并返回指向已分配内存的指针。
这正是您正在做的事情,但您可以让图书馆为您处理。
(我还谦卑地建议在你的函数中使用“focal”这个词来命名变量吗?)(另外,我也不清楚为什么你的struct中的focalPoints
是一个指针-pointer。你只需要一个结构数组 - 一个指针就可以了。)
考虑以下(稍微广泛)重写;希望它在某种程度上有所帮助。
typedef struct{
CGPoint *points; // Single pointer
NSUInteger count;
CGRect boundingRect;
} FocalPoints;
// Renamed to match Apple's style, like e.g. CGRectIntersectsRect()
void FocalPointsAddPoint (FocalPoints *, CGPoint);
void FocalPointsAddPoint (FocalPoints *f, CGPoint thePoint){
if (thePoint.x == CGFLOAT_MAX) return;
if (!CGRectContainsPoint(f->boundingRect, thePoint)) return;
NSUInteger origCount = f->count; // |count| is typed as NSUInteger; |origCount|
NSUInteger newCount = origCount + 1; // and |newCount| should be consistent
// Greatly simplified by using realloc()
f->points = (CGPoint *) realloc(f->points, newCount * sizeof(CGPoint));
(f->points)[newCount-1] = thePoint;
f->count = newCount;
}
int main(int argc, const char * argv[])
{
@autoreleasepool {
// Just for testing; any point should be inside this rect
CGRect maxRect = CGRectMake(0, 0, CGFLOAT_MAX, CGFLOAT_MAX);
// Can initialize |points| to NULL; both realloc() and free() know what to do
FocalPoints fp = (FocalPoints){NULL, 0, maxRect};
int i;
for( i = 0; i < 10; i++ ){
FocalPointsAddPoint(&fp, CGPointMake(arc4random() % 100, arc4random() % 100));
NSLog(@"%@", NSStringFromPoint(fp.points[i]));
}
}
return 0;
}