C:无法接收指向结构数组的指针
我有以下结构和函数C:无法接收指向结构数组的指针,c,arrays,pointers,struct,C,Arrays,Pointers,Struct,我有以下结构和函数 // KEY // ---------------------------- struct key { double k1, k2; }; // CELL // ---------------------------- struct cell { double x, y, h, g, rhs; struct key *keys; }; void cellPrintData(struct cell *c) { printf("\n\tCE
// KEY
// ----------------------------
struct key {
double k1, k2;
};
// CELL
// ----------------------------
struct cell {
double x, y, h, g, rhs;
struct key *keys;
};
void cellPrintData(struct cell *c) {
printf("\n\tCELL\n\t.............\n");
printf("\t%f\n", c->x);
printf("\t%f\n", c->y);
printf("\t%f\n", c->g);
printf("\t%f\n", c->h);
printf("\t%f\n", c->rhs);
printf("\t%f\n", c->keys->k1);
printf("\t%f\n", c->keys->k2);
}
/* cellCopyValues
* ----------------------------
* Copy values from source cell
* into target cell.
*/
void cellCopyValues(struct cell *targetcell, struct cell *sourcecell) {
targetcell->x = sourcecell->x;
targetcell->y = sourcecell->y;
targetcell->h = sourcecell->h;
targetcell->g = sourcecell->g;
targetcell->rhs = sourcecell->rhs;
targetcell->keys->k1 = sourcecell->keys->k1;
targetcell->keys->k2 = sourcecell->keys->k2;
}
/* cellDuplicate
* ----------------------------
* Create a duplicate cell using
* values from given cell and return it.
*/
struct cell * cellDuplicate(struct cell *c) {
struct cell *c2 = (struct cell *) malloc(sizeof(struct cell));
if (c2 == NULL) {
printf("--> Unable to malloc *c2!\n");
errno = ENOMEM;
return NULL;
}
c2->keys = (struct key *) malloc(sizeof(struct key));
if (c2->keys == NULL) {
printf("--> Unable to malloc *c2->keys!\n");
errno = ENOMEM;
return NULL;
}
cellCopyValues(c2, c);
return c2;
}
现在,我在从这个方法接收struct数组时遇到了一个问题:
/* cellGetNeighbors()
* ----------------------------
* Gets the neighbors of a cell
*/
struct cell * cellGetNeighbors(struct cell *c, struct cell *sstart, struct cell *sgoal, double km) {
int i;
// CREATE 8 CELLS
struct cell cn[8];
//cellPrintData(c);
for(i = 0; i < 8; i++) {
cn[i] = *cellDuplicate(c);
}
// MAKE THEM NEIGHBORS
cn[0].y -= _DISTANCETOMOVE;
cn[1].x -= _DISTANCETOMOVE;
cn[2].y += _DISTANCETOMOVE;
cn[3].x += _DISTANCETOMOVE;
cn[4].x -= _DISTANCETOMOVE;
cn[4].y -= _DISTANCETOMOVE;
cn[5].x -= _DISTANCETOMOVE;
cn[5].y += _DISTANCETOMOVE;
cn[6].x += _DISTANCETOMOVE;
cn[6].y += _DISTANCETOMOVE;
cn[7].x += _DISTANCETOMOVE;
cn[7].y -= _DISTANCETOMOVE;
// CALCULATE g, h, rhs, key
for(i = 0; i < 8; i++) {
cn[i].g = cellG(&cn[i], sgoal);
cn[i].h = cellH(&cn[i], sstart);
cn[i].rhs = _INFINITY;
cn[i].keys = cellCalculateKey(&cn[i], km);
//cellPrintData(&cn[i]);
}
// STORE THESE NEIGHBORS IN FILE.
struct cell *cptr = &cn[0];
cellPrintData(&cn[2]);
return cptr;
}
方法2:(接受者)
这也导致k1和k2-和分段故障的值非常大。我做错了什么。。谢谢……) 您的问题就在
CellGetNeights
中:
struct cell cn[8];
您正在堆栈上分配cn
,因此当cellgetneights
函数完成并返回时,cn
的值(它的cellgetneights
版本)将不再有效,并且cellMinNeighbor
中的cn
将指向用于其他内容的堆栈块
您有两个简单的选择:
struct cell
数组传递到cellgetnextries
中,以便调用者负责分配该内存cn
分配到cellgetneights
内的堆(即malloc
)上,并按原样返回。当然,调用方必须释放CellGetNeights
返回值,当它完成时(这个事实应该作为CellGetNeights
接口的一部分进行记录)
cellFree
函数来正确释放单个单元格。cellFree
函数是个好主意,因为您的struct cell
中有一个指针,需要释放该指针。当然,如果你需要使用一个不包含八个元素的数组,这就更加复杂了;如果发生这种情况,那么还必须通过向getCellNeights
添加额外的指针参数来返回数组大小。如果事情发展到这一点,那么您需要添加一个单独的结构:
struct cells {
int n; /* How many cells there are */
struct cell *items; /* The cells themselves */
}
以及一组用于分配和释放这些新结构的函数
我猜在cellCalculateKey
中也存在类似的堆栈与堆问题
而且,您不需要这样做:
struct cell *cptr = &cn[0];
cellPrintData(&cn[2]);
return cptr;
cn
数组将在没有您干预的情况下衰减为指针,这很好:
cellPrintData(&cn[2]);
return cn;
此外,由于我已经在这里写了一本书,您不需要在C中使用malloc
(或calloc
或realloc
或任何其他返回void*
)的返回,这样做可以掩盖问题。那么,你这样说:
struct cell *c2 = (struct cell *) malloc(sizeof(struct cell));
/* ... */
c2->keys = (struct keys *) malloc(sizeof(struct key));
你应该说:
struct cell *c2 = malloc(sizeof(struct cell));
/* ... */
c2->keys = malloc(sizeof(struct key));
还有一件事,这里有一个内存泄漏:
for(i = 0; i < 8; i++) {
cn[i] = *cellDuplicate(c);
}
而
cellDuplicateContent
只需复制单个成员,当然,将键的数据分配为指针(即cellCopyValues
加上键的分配)。您的问题就在CellGetNeights
中:
struct cell cn[8];
您正在堆栈上分配cn
,因此当cellgetneights
函数完成并返回时,cn
的值(它的cellgetneights
版本)将不再有效,并且cellMinNeighbor
中的cn
将指向用于其他内容的堆栈块
您有两个简单的选择:
将八个struct cell
数组传递到cellgetnextries
中,以便调用者负责分配该内存
将cn
分配到cellgetneights
内的堆(即malloc
)上,并按原样返回。当然,调用方必须释放CellGetNeights
返回值,当它完成时(这个事实应该作为CellGetNeights
接口的一部分进行记录)
我建议使用第二个选项,并建议构建一个单独的cellFree
函数来正确释放单个单元格。cellFree
函数是个好主意,因为您的struct cell
中有一个指针,需要释放该指针。当然,如果你需要使用一个不包含八个元素的数组,这就更加复杂了;如果发生这种情况,那么还必须通过向getCellNeights
添加额外的指针参数来返回数组大小。如果事情发展到这一点,那么您需要添加一个单独的结构:
struct cells {
int n; /* How many cells there are */
struct cell *items; /* The cells themselves */
}
以及一组用于分配和释放这些新结构的函数
我猜在cellCalculateKey
中也存在类似的堆栈与堆问题
而且,您不需要这样做:
struct cell *cptr = &cn[0];
cellPrintData(&cn[2]);
return cptr;
cn
数组将在没有您干预的情况下衰减为指针,这很好:
cellPrintData(&cn[2]);
return cn;
此外,由于我已经在这里写了一本书,您不需要在C中使用malloc
(或calloc
或realloc
或任何其他返回void*
)的返回,这样做可以掩盖问题。那么,你这样说:
struct cell *c2 = (struct cell *) malloc(sizeof(struct cell));
/* ... */
c2->keys = (struct keys *) malloc(sizeof(struct key));
你应该说:
struct cell *c2 = malloc(sizeof(struct cell));
/* ... */
c2->keys = malloc(sizeof(struct key));
还有一件事,这里有一个内存泄漏:
for(i = 0; i < 8; i++) {
cn[i] = *cellDuplicate(c);
}
而cellDuplicateContent
将只复制单个成员,当然,将键的数据分配为指针(即cellCopyValues
加上键的分配)。看起来CellGetNeights正在返回堆栈内存——它返回指向&cn[0]的cptr。一旦该方法返回,您在堆栈上声明的任何内容都不再有效。您正在将单元格复制到其中,因此可能只需要对数组进行malloc。请注意,您最终也需要释放该数组。看起来CellGetNeights正在返回堆栈内存——它返回指向&cn[0]的cptr。一旦该方法返回,您在堆栈上声明的任何内容都不再有效。您正在将单元格复制到其中,因此可能只需要对数组进行malloc。请注意,您需要