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。请注意,您需要