2012-03-19 55 views
1

我有一个结构CGPoint的c数组。当另一个CGPoint被添加时,我需要替换这个数组。我发誓我正在做这件事,它似乎很好,但最终我会得到一个EXC_BAD_ACCESS。我错过了什么?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)

现在,这里的该用新的替换点阵列的功能:

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

我不知道全部,但我认为newPoints [i]是一个CGPoint,而* focal-> focalPoints [i]是一个CGPoint指针... – FrankieTheKneeMan 2012-03-19 20:45:42

+1

你有没有考虑使用链表,甚至'NSMutableArray' /'NSValue',这样你就不会在每次添加一个点时分配,复制和释放整个东西? – 2012-03-19 20:49:40

+0

fPoints的原始malloc未在技术上使用。但是我分配空间是因为AddFocalPoint函数会自由调用它,并且我不想释放未被malloc'd的空间。 '&fPoints'为fPoints添加一个额外的指针。我这样做是因为我相信这是取代c-array的唯一方法。 – 2012-03-19 20:49:43

回答

3

这是一个有点长镜头,但也许有在*focal->focalPoints[i]与操作者优先的问题。你有没有尝试根据你想要实现的内容添加括号?

+0

括号是什么意思?我将它放在哪里? – 2012-03-19 20:55:35

+0

在'*焦点 - > focalPoints [我]',我不知道它是'*(focal-> focalPoints [i ])','*(focal-> focalPoints)[i]','(* focal) - > focalPoints [i]'..我想你明白我在这里想说什么 – ksol 2012-03-19 20:57:34

+0

嗯,你知道什么。你是对的,我添加了一行'CGPoint * focalPoints = * focal-> focalPoints'',我像这样访问它:'newPoints [i] =(i 2012-03-19 21:03:05

2

相信这个问题带有地方GCPoint *fPoints分配为&fPoints计算结果为一个地址......这不再是一次函数退出有效。

(其所被分配与malloc精细的数据。)

+0

该函数退出后不访问该结构。我通过引用将结构传递给另一个函数。当该函数返回时,我将在结构中修改的数据传递给另一个函数(所有函数仍然在创建该结构的函数中)。然后该函数退出,结构被破坏。它不在其他地方访问。 – 2012-03-19 20:52:59

+0

那么,有我的想法。祝你好运整理出来:( – 2012-03-19 21:10:16

1

除了我在评论中提出的建议,使用链表/ NSMutableArray的,我的另一项建议是,你使用realloc()而是不断利用malloc(),复制的手,然后free()荷兰国际集团旧的分配。

void * realloc(void *ptr, size_t size);
realloc()函数试图改变分配的大小指向ptrsize,并返回ptr。如果没有足够的空间来放大由ptr指向的内存分配,realloc()会创建一个新的分配,将复制尽可能多的由ptr指向的旧数据,以适应新分配,释放旧分配并返回指针分配给内存。

这几乎是你在做什么,但你可以让图书馆为你处理它。 (也可以虚心地建议使用“焦点”这个词,稍微少一点来命名函数中的变量?)(另外,我并不清楚为什么你的结构中的focalPoints是指针指针。你只需要一个结构数组 - 单个指针应该没问题。)

考虑下面的(有点广泛的)重写;希望这有助于某种方式。

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; 
} 
+0

优秀,谢谢,对不起,我已经接受了另外一个答案,但是我的确投了你的票。首先,我不能使用obj-c对象,因为我使用了ARC,所以不允许这样做,所以NSMutableArray出来了,我不知道'realloc是真的简化了一些东西,谢谢!我为我的c数组使用双指针的原因是我根本无法用新的数组替换它。当我退出功能时,我是如何尝试的n结构保留了一个指向旧数组的指针。我在这里找到了答案:http://stackoverflow.com/questions/1106957/pass-array-by-reference-in-c。 – 2012-03-19 22:17:09

+0

很高兴它有帮助。不要担心接受;我有更多无用的代表,比我知道怎么处理反正。应该有一种方法可以让一个对象进入一个结构,即使使用ARC(我认为'__unsafe_unretained'可能是你所需要的),但它可能不值得头疼。 – 2012-03-19 22:25:06

+0

是的,这可能会工作,但我现在得到这个工作,所以我不会乱它。此外,我很喜欢回到一些c。 – 2012-03-19 22:57:36