C-从结构内部的指针访问指针会导致分割故障



我很难尝试从 cart_t中的 **addr变量访问 item_t指针的成员。cart_t的定义如下:

typedef struct cart_struct {
    item_t **addr;
    int ptr;
    float total;
} cart_t;

我已经初始化了,并使用以下代码将项目添加到**addr

cart_t *cart_append_item(cart_t *cart, item_t *item) {
    if (cart == NULL || item == NULL)
        return NULL;
    item_t **new = (item_t**) malloc(sizeof(item_t*) * (cart->ptr + 1));
    if (new == NULL) {
        return NULL;
    }
    int i;
    for (i=0; i<cart->ptr; i++) {
        new[i] = cart->addr[i];
    }
    new[i+1] = item;
    if (cart->addr != NULL) {
        free(cart->addr);
    }
    cart->addr = new;
    cart->ptr += 1;
    printf("price %f, quantity %d, total %fn", new[cart->ptr]->price, new[cart->ptr]->quantity, new[cart->ptr]->price * new[cart->ptr]->quantity); // this works.
    //printf("total_prev %fn", cart->total);
    cart->total += item->price * item->quantity;
    //printf("total %fn", cart->total);
    return cart;
}

您可以在上面的代码上看到,调试printf实际上有效。但是,当我以后在cart.addr[n]上尝试进行操作时,会导致分割错误:

// cart_t canteen_cart
// item_t *item_current
...
if (cart_append_item(&canteen_cart, item_current) == NULL) {
    // error. clean up
}
...
printf("[TEST] price %f, quantity %d, total %fn", canteen_cart.addr[canteen_cart.ptr-1]->price, canteen_cart.addr[canteen_cart.ptr-1]->quantity, canteen_cart.addr[canteen_cart.ptr-1]->price * canteen_cart.addr[canteen_cart.ptr-1]->quantity); // segmentation fault
...

谢谢!


int main()的摘要:

int main() {
    cart_t canteen_cart;
    canteen_cart.addr = NULL;
    canteen_cart.ptr = 0;
    canteen_cart.total = 0.0f;
    item_t *item_current = NULL;
    ...
    a hundred of lines later of user input thingy
    ...
    if (state == STATE_CHECKOUT) {
        printf("[TEST] %dn", canteen_cart.addr == NULL); // returns 0
        printf("[TEST] %dn", canteen_cart.ptr > 0); // returns 1, there are some items in the array
        printf("price %f, quantity %d, total %fn", canteen_cart.addr[canteen_cart.ptr-1]->price, canteen_cart.addr[canteen_cart.ptr-1]->quantity, canteen_cart.addr[canteen_cart.ptr-1]->price * canteen_cart.addr[canteen_cart.ptr-1]->quantity);
    print_view_checkout(&canteen_cart); // SEGMENTATION FAULT HERE
    }
    cart_free_items(&canteen_cart); // free cart and all the members within it.
    return 0;
}

现在,当我们可以看到您如何初始化 canteen_cart时,请从 cart_append_item函数中获取此行:

new[i+1] = item;

在第一个呼叫cart_append_item函数的呼叫中,cart->ptr的值(确实命名不佳)是0。这意味着循环不会迭代,并且i的值将为零。这意味着您实际上是在执行new[1] = item,其中new只有一个索引0的单个元素的空间。当然,这本书是从范围出发的,这导致了不确定的行为,使您的整个程序不正确的和无效。容易崩溃。

您也继续写出每个连续调用cart_append_item的范围。

简单的解决方案?改用new[cart->ptr] = item


然后,关于我的realloc注释,如果使用realloc

,您可以使功能更短,更简单
cart_t *cart_append_item(cart_t *cart, item_t *item) {
    if (cart == NULL || item == NULL)
        return NULL;
    item_t **new_items = realloc(cart->addr, sizeof *cart->addr * cart->ptr + 1);
    if (new_items == NULL) {
        return NULL;
    }
    cart->addr = new_items;
    // Add the new item
    cart->addr[cart->ptr++] = item;
    cart->total += item->price * item->quantity;
    return cart;
}

相关内容

  • 没有找到相关文章

最新更新