免责声明:我对C ++非常非常新。两年前我参加了一个班级,现在我正在上另一个班级,所以试图回到心态是很困难的。话虽这么说,我知道我的代码非常糟糕;我想要帮助和建设性的批评,所以请避免彻底抨击,因为我知道我真的不知道我在做什么。
目标:我正在编写一个程序,它接受两个形式为{1 2 3}(任意大小)的用户输入集,并对它们执行一些操作。但是我只是在阅读它们时遇到了麻烦。这是一个头文件的快速片段,显示了我将要问的函数:
class Set{
public:
Set(); //Constructor for empty set.
Set(int element); //Constructor for set of one element
~Set();
unsigned int getSize() const;
int operator[](const int e) const;
friend ostream& operator<<(ostream& oss, const Set& output);
friend istream& operator>>(istream& ss, Set& target);
private:
int size;
int *elements[];
void resize(unsigned int new_size);
};
还有更多,但我只是向你展示所有必要的东西。
对于赋值,我们创建一个名为Set的类,但该集必须存储为数组。我们为每个Set都有一个指针数组(即Set类带有int * elements [])。我们需要重载“&gt;&gt;”运算符将用户输入转换为Set。用户输入两个集。我们假设用户足够聪明,可以以{1 2 3 4}的确切形式输入,但它可以是任何大小。这是我的重载&gt;&gt;。
istream& operator>>(istream& ss, Set& target){
//The constructor Set target; creates an empty Set with array size=0.
char c;
if (ss.peek()=='}') ss >> c;
if (ss.peek()==EOF) ss >> c;
ss >> c; //First we read in the '{' character.
int num;
while (ss.peek()!='}'){
ss >> num;
target.resize(target.getSize()+1);
*target.elements[target.getSize()-1]=num;
};
return ss;
};
getSize()只是一个返回值“size”的函数。上面代码片段的目标是创建一个空Set,然后对于介于“{”和“}”之间的每个int,我们将数组的大小调整为1,然后将该int放入数组的下一个元素中。此外,对于我来说,流仍然像指针一样抽象,所以这就是为什么这似乎有点蛮力。
我遇到的问题是调整大小。我希望 - 显然 - 调整大小以改变大小,但它不允许这样做。我想要完成的是调整大小以将被调用的Set的*元素指针更改为指向具有new_size元素数量的新数组。然后我想释放该指针以避免内存泄漏。
void Set::resize(unsigned int new_size){
if (size!=new_size){
int *newelements = new int[new_size];
for (int i=0; i<new_size || i<size; i++){
newelements[i] = *elements[i];
};
*elements = newelements;
delete newelements;
if (size>new_size) size=new_size;
};
};
我知道的一件事是错的:当我在“&gt;&gt;”的定义中调用newset.resize时,
newelements[i] = *elements[i];
由于“num”尚未分配给* newset.elements [i],行正试图分配一些尚不存在的东西。但是,如果我尝试在“&gt;&gt;”中切换这些顺序所以它就这样......
*target.elements[target.getSize()]=num;
target.resize(target.getSize()+1);
...这应该没有意义,因为目标数组的大小是0,所以我不能说target [0] = num;
我知道的另一件事是错误的:我使用指针的方式必须错误,因为如果我在调整大小定义中尝试说size = new_size ,我收到“EXC_BAD_ACCESS”错误。实际上,如果我按原样运行,我会收到相同的错误消息。
此外,在作业中,我们被告知“如果new_size严格小于大小,则调整大小应该只更新大小。”我不明白这是如何工作的。如果我们必须从size = 0的初始化数组开始,那么我们怎样才能让它更大呢?
我希望我已经包含足够的内容以获得一些帮助。我感谢任何有助于我理解指针以及如何使用它们的东西。非常感谢你!
答案 0 :(得分:0)
我不确定我是否拿起了所有东西,但是扫描了代码:
int *elements[];
在C ++中是非法的,尽管有些编译器允许它作为扩展。 您必须指定数组大小。
如果我用gcc编译,它会告诉我:
警告:ISO C ++禁止零大小数组'元素'[-Wpedantic]
int * elements [];
if (size!=new_size)
行始终为true,除非size
不等于new_size
。
您最有可能只在new_size
更大而不是size
时调整数组大小。
3. i<new_size || i<size
应该只是i<size
。
4.在newelements[i] = *elements[i];
中,*elements[i]
相当于*(elements[i])
而不 (*elements)[i]
,您确定这是您想要的吗?
5。
*elements = newelements;
delete newelements;
第一行使elements
的第一个元素(指针)指向新分配的内存。第二行然后删除该内存,所以现在elements
的第一个元素现在指向释放的内存。那不是你想要的。
请记住,当您为指针指定指针时,它会使两个指针指向同一个内存。您需要做的是删除旧内存,然后将指针指定为指向新分配的内存。
6.还要记住delete []
与delete
不同。删除内存块时,您需要使用delete []
。
希望这一切都是为了学习目的。在真正的C ++代码中,您将改为使用std::vector
。