[英]C: Freeing a malloc'd array at the wrong time?
我有一個struct cell
->
struct cell {
double x, y, h, g, rhs;
struct key *keys;
};
我正在使用以下方法釋放單元格->
void cellFree(struct cell *c) {
// Free the keys
free(c->keys);
// Free the cell itself.
free(c);
}
void cellFreeSors(struct cell *cn) {
int i;
for(i = 0; i < 5; i++) {
// Free keys
free(cn[i].keys);
}
// Free array
free(cn);
}
現在,我所創建的一個malloc數組面臨一個怪異的問題。 基本上,我試圖找到一個單元格的鄰居,並使用以下兩種方法根據其值進行一些處理->
struct cell * cellGetSuccessors(struct cell *c, struct cell *sstart, struct cell *sgoal, double km) {
int i;
// CREATE 5 CELLS
struct cell *cn = malloc(5 * sizeof (struct cell));
if (cn == NULL) {
printf("--> Unable to malloc *cn!\n");
errno = ENOMEM;
return NULL;
}
for(i = 0; i < 5; i++) {
cn[i].keys = malloc(sizeof(struct key));
if (cn[i].keys == NULL) {
printf("--> Unable to malloc *cn[%d].keys!\n", i);
errno = ENOMEM;
return NULL;
}
cellCopyValues(&cn[i], c);
}
// MAKE THEM NEIGHBORS
// PROCESS
return cn;
}
double cellRHS(struct cell *c, struct cell *sstart, struct cell *sgoal, double km, struct cell * prevCell) {
// GET NEIGHBORS of c
struct cell *cn = cellGetSuccessors(c, sstart, sgoal, km);
double minsum;
// SOME PROCESS TO UPDATE minsum
minsum = 5.232111; // SAY
// Free memory
cellFreeSors(cn);
return minsum;
}
麻煩的是,當我在cellRHS()
調用cellFreeSors()
, cellRHS()
遇到問題..這就是這些函數的調用方式。
struct cell *u = cellCreateNew();
u->rhs = cellRHS(u, sstart, sgoal, km, prevCell);
queueAdd(&U, u);
當我嘗試打印隊列時,這給了我一個分段錯誤->
QUEUE CONTENTS
==================================================================
F -> 0x2354550
L - >0x2354550
(1) [0x2354550] X 50.000000, Y 45.000000 PREV: (nil) NEXT: 0x4014000000000000
Segmentation fault
如您所見,由於某種原因,該條目的NEXT似乎已初始化。 在不使用cellRHS()
情況下執行相同的代碼也可以正常工作cellRHS()
>
struct cell *u = cellCreateNew();
queueAdd(&U, u);
QUEUE CONTENTS
==================================================================
F -> 0x2354550
L - >0x2354550
(1) [0x2354550] X 50.000000, Y 45.000000 PREV: (nil) NEXT: (nil)
為什么cellFreeSors()
導致此問題? 我對超出cellRHS
范圍的u產生的鄰居沒有用。 我究竟做錯了什么?
謝謝..
**編輯queue_node的結構是
/* QUEUE NODE
* ----------------------------
* Contains a struct cell c and
* reference to next queue_node
*/
struct queue_node {
struct cell *c;
struct queue_node *next;
struct queue_node *prev;
};
/* PRIORITY QUEUE
* ----------------------------
* The queue itself, with first
* and last pointers to queue_nodes
*/
struct priority_queue {
struct queue_node *first;
struct queue_node *last;
};
queuePrint()
方法顯示隊列內容->
void queuePrint(struct priority_queue *q)
{
printf("\n\n\tQUEUE CONTENTS\n\t==================================================================\n");
int i = 1;
struct queue_node *temp = q->first;
printf("\tF -> %p\n\tL -> %p\n", q->first, q->last);
while(temp != NULL) {
printf("\t(%d) [%p]\tX %f, Y %f\tPREV: %p\tNEXT: %p", i, temp, temp->c->x, temp->c->y, temp->prev, temp->next);
printf("\n");
temp = temp->next;
i++;
}
printf("\n\n");
}
這里的一些建議:
使用集中式allocCell()和freeCell()方法。 這使您可以精確地跟蹤每個分配和釋放的單元格。
在每個單元格上放置一個ID。 同樣,這允許進行詳細的跟蹤。 如果空間有限,可以將其編譯為生產方式,將其編譯為調試方式。
為單元編寫跟蹤例程,以查看例程僅釋放分配的單元,任何單元僅釋放一次,依此類推。您甚至可以編寫哈希表來存儲分配和釋放的單元的ID(當然只是在調試過程中)並編寫驗證檢查。
如果不這樣做,您可能會再次遇到內存錯誤。
即使執行此操作,也將再次遇到內存錯誤,但是這些工具將幫助您下次更快地對其進行跟蹤。
切換到C#或Java,不釋放任何東西:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.