我完全失去了困惑,可以使用一些帮助。 我目前正在开发一个基于命令行的小游戏。为此我写了一个类 Inventory ,动态创建一个 invSpace - 对象的数组,每个空格代表一对指向 Item 的指针(另一类我的)和一个整数,描绘了一个数量。这是代码:
class invSpace {
public:
Item *item;
int quantity;
invSpace() {
item = NULL;
quantity = 0;
}
};
class Inventory {
private:
invSpace* spaces = NULL;
size_t size;
public:
int free_space() {
int free = 0;
for (int i = 0; i < size; i++) {
if (spaces[i].item == NULL) {
free++;
}
}
return free;
}
Inventory() {}
Inventory(size_t new_size) {
size = new_size;
spaces = new invSpace[size];
for (int i = 0; i < size; i++) { //I know this is obsolete because
spaces[i].item = NULL; //of the invSpace constructor, I
spaces[i].quantity = 0; //just did this for testing
}
~Inventory() {
delete[] spaces;
}
invSpace& operator[](int index) {
return spaces[index];
}
};
此课程中还有更多方法,例如添加,删除和搜索项目,但这些方法现在并不重要。所以这基本上只是一个对象中的一个简单数组,在构造函数中动态分配内存并使用一些额外的方法。创建后,数组包含零元素或Items,因此free_space()
方法应返回数组的大小。但它并没有。它返回大约一半的大小。
我的第一个想法是分配出了问题。但是第二眼我注意到库存在创建后直接完全没问题;如同请求的空间一样多,它们都设置为item = NULL / quantity = 0。但是在getline()
开始调用main()
扫描用户输入并将其保存到字符串以进行进一步分析后,一些空格会被随机地址和整数填充。
更奇怪的是,每次getline()
的新调用都会释放一些空格,其他一些空格会被填满。就我的调试,实验和测试而言,这些地址都不属于我程序中的任何变量,它们只是随机的。此外,在任何时候都不会干扰Inventory和getline()
函数或它返回的字符串。事实上,在创建之后,free_space()
方法旁边的代码中的任何地方都不会使用此对象的任何部分。更奇怪的是 Inventory 类中的 spaces 被标记为私有,因此需要一个方法来插入这个指针/数组(或者我希望如此)。
getline()
和cin
会出现此问题,但C&<stdio.h>
输入流功能不会出现此问题。使用malloc()
代替new[]
没有任何区别。当然,我可以使用类似scanf()
的东西来从控制台读取。不过,我只是想知道为什么会发生这些事情。我完全不知道。
提前感谢您的每一个答案!
编辑:
我缩小了整个代码,以便它仍然产生相同的错误,也改变了free_space()
,以便打印地址和整数(如果存在):
#include <iostream>
#include <string>
#include <map>
using namespace std;
class Item {
public:
static map<string, Item*> itemlist;
string name;
string description;
Item() {}
Item(const string new_name, const string new_description) {
name = new_name;
description = new_description;
itemlist.insert(pair<string, Item*> (name, this));
}
};
map<string, Item*> Item::itemlist;
/*The more Items are declared, the more random adresses appear in the
inventory*/
Item item01("sword", "A sharp and deadly weapon.");
Item item02("shield", "This will protect you. To a certain extent.");
Item item03("stick", "What is this for exactly?");
Item item04("bottle of water", "A bottle full of refreshing spring water.");
class invSpace {
public:
Item *item;
int quantity;
invSpace() {
item = NULL;
quantity = 0;
}
};
class Inventory {
private:
invSpace* spaces = NULL;
size_t size;
public:
int free_space() {
int free = 0;
for (int i = 0; i < size; i++) {
if (spaces[i].item == NULL) {
free++;
cout << i << " = free" << endl;
}
else {
cout << spaces[i].item << " / " << spaces[i].quantity << endl;
}
}
return free;
}
Inventory() {}
Inventory(size_t new_size) {
size = new_size;
spaces = new invSpace[size];
for (int i = 0; i < size; i++) {
spaces[i].item = NULL;
spaces[i].quantity = 0;
}
}
~Inventory() {
delete[] spaces;
}
};
class Player {
public:
string name;
Inventory inventory;
Player(const string new_name) {
inventory = Inventory(40);
name = new_name;
}
};
Player player("Me");
int main() {
string input;
//Inventory inventory(40); //no error when declared outside the Player class
while (1) {
cout << "\n>> ";
getline(cin, input);
if (input == "x") {
break;
}
else {
player.inventory.free_space();
}
}
}
我注意到的一些事情:如果库存不是Player-object的一部分,则不会发生错误。如果是,但没有声明项目,则只有第一个库存空间在第一次调用getline()
后收到随机地址(和int值)。
物品越多,我得到的随机地址越多,似乎......