除非使用cout,否则为什么我的值不正确?

时间:2018-10-10 12:03:57

标签: c++

我正在为学校分配C ++,但是遇到了一个特殊的问题。这很可能是内存损坏或其他原因,但是由于我在C ++中的表现平平,所以我不知道如何解决它。

void Inventory::addItem(Item *item, const int stackCount) {
    //find the item
    Item *fi = findItem(item->id);

    if(fi == nullptr)
    {
        Item *newItem = (Item *)malloc(sizeof(Item));
        //std::cout << stackCount << std::endl;
        memcpy(&newItem, &item, sizeof(Item));
        newItem->stack = stackCount;
        current.push_back(newItem);
    }
}

我有这段代码,在这里它将项目的属性复制到另一个项目。这可以正常工作,并且可以处理所有内容。除了stackCount变量之外,还有一些奇怪的事情。

有一个注释cout,注释掉了stackCount值是错误的。大约在32k左右。

如果未将其注释掉,则该值将正确!是1! (我正在其他功能中对此进行测试)

当放在memcpy语句后面时,该值始终是错误的。当然哪个使我相信这确实是内存损坏。

所以我真的很困惑。 c ++在这里到底在做什么?

2 个答案:

答案 0 :(得分:3)

memcpy(&newItem, &item, sizeof(Item));

您在这里所说的是从item的地址(也就是指向Item的指针的指针)复制到newItem的地址(又是指向Item的地址)指向sizeof(Item) != sizeof(Item**)的指针。

由于这两个都是堆栈变量,而且我猜为memcpy,因此您在这里调用未定义的行为。

StackSize变量仅在打印时才起作用的原因纯属您的运气;编译器最喜欢的是只是在堆栈上移动一些变量以尝试优化堆栈/寄存器的使用,然后将变量移出要覆盖的区域。

由于您使用的是C ++,因此不应首先使用operator=。编写一个复制构造函数和一个Item来复制{{1}}值。

答案 1 :(得分:0)

Memcpy应该获得目标地址和源地址。 您正在传递“地址到地址”。 更改:

memcpy(&newItem, &item, sizeof(Item));

memcpy(newItem, item, sizeof(Item));

此外,如@Bathsheba和@ Some-programmer-dude和@yksisarvinen所述,您不应使用malloc。考虑创建一个复制构造函数和/或赋值运算符。