2012-03-19 57 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