所以我有一个这样的任务,我需要使用动态数组扩展而不是向量。这让我疯了,因为我过去已经成功完成了几次,而且我一直在试图弄清楚过去2天这个问题有多么糟糕。
在我的代码中,每次我的数组变满时,我都会尝试将stringsArr的大小加倍。
我的stringsArr最初是arrCapacity 4(它的最大尺寸),包含5个值。
stringsArr是我的StringSet类的私有属性。
我已经尝试过使用堆(我应该为分配执行此操作的方式)和堆栈(仅作为检查)。
printStringsArr(): 我正在使用此函数将最终的数组打印到控制台:
void StringSet::printStringsArr() {
for (int i = 0; i < arrIndex; i++) {
cout << i << ": " << stringsArr[i] << endl;
}
cout << "\n" << arrCapacity << endl;
}
我添加了2个for循环来显示我的stringsArr的内容,因为当我在堆上声明一个新数组时,我不明白为什么我的stringsArr的内容会像这样改变。
if (arrIndex == arrCapacity) {
int newCapacity = (arrCapacity * 2);
/* Display content of stringsArr
before tmpArray declaration*/
for (int i = 0; i < arrIndex; i++) {
cout << "." << stringsArr[i] << endl;
}
cout << "\n" << endl;
// Allocate on the heap the new empty array
string *tmpArr = new string[newCapacity];
/* Display te content of stringsArr after declaring
tmpArr on the heap*/
for (int i = 0; i < arrIndex; i++) {
cout << "." << stringsArr[i] << endl;
}
// Copy everything
for (int i = 0; i < arrCapacity; i++) {
tmpArr[i] = stringsArr[i];
}
// Update arrCapacity to its new value.
arrCapacity = newCapacity;
delete [] stringsArr;
stringsArr = tmpArr;
}
// From the 1st for loop.
.Dog
.Cat
.Turtle
.Lion
// For the 2nd for loop,
// mysteriously, only the first value is left.
.Dog
.
.
.
// And for the "printStringsArr()" function.
0: Dog
1:
2:
3:
4: Fish
我确信我完全错过了一些东西,但我根本不知道它是什么......
if (arrIndex == arrCapacity) {
int newCapacity = (arrCapacity * 2);
for (int i = 0; i < arrIndex; i++) {
cout << "." << stringsArr[i] << endl;
}
cout << "\n" << endl;
string *tmpArr[newCapacity];
for (int i = 0; i < arrIndex; i++) {
cout << "." << stringsArr[i] << endl;
}
// Copy everything
for (int i = 0; i < arrCapacity; i++) {
tmpArr[i] = &stringsArr[i];
}
arrCapacity = newCapacity;
delete [] stringsArr;
stringsArr = *tmpArr;
}
// From the 1st for loop.
.Dog
.Cat
.Turtle
.Lion
// For the 2nd for loop.
.Dog
.Cat
.Turtle
.Lion
// And for the "printStringsArr()" function.
0: Dog
1: Cat
2: Turtle
3: Lion
4: Fish
我的大问题是&#34;为什么在我在堆上声明一个新的空数组后,我的stringsArr值会消失?&#34;。
对我来说,到目前为止,这是黑魔法,我想了解为什么会发生这种情况以及如何解决它。
感谢您的帮助。
#include <iostream>
using namespace std;
int main()
{
class StringSet {
public:
StringSet() {
this->arrCapacity = 4;
this->arrIndex = 0;
}
bool insert(string str) {
// If string already present, return false.
for (int i =0; i < arrCapacity; i++) {
if (stringsArr[i] == str) {
return false;
}
}
// Otherwise, insert the string at the next available index in our array.
// If the arrCapacity is less or equal to the next index, increase the array
// size two-folds.
// arrIndex always point to the top empty cell of the array.
// arrIndex points to the next free cell on the array
if (arrIndex == arrCapacity) {
int newCapacity = (arrCapacity * 2);
/* Display content of stringsArr
before tmpArray declaration*/
for (int i = 0; i < arrIndex; i++) {
cout << "." << stringsArr[i] << endl;
}
cout << "\n" << endl;
// Allocate on the heap the new empty array
string *tmpArr = new string[newCapacity];
/* Display te content of stringsArr after declaring
tmpArr on the heap*/
for (int i = 0; i < arrIndex; i++) {
cout << "." << stringsArr[i] << endl;
}
// Copy everything
for (int i = 0; i < arrCapacity; i++) {
tmpArr[i] = stringsArr[i];
}
// Update arrCapacity to its new value.
arrCapacity = newCapacity;
delete [] stringsArr;
stringsArr = tmpArr;
}
stringsArr[arrIndex] = str;
arrIndex++;
return true;
}
//Dump the content of stringsArr to the console.
void printStringsArr() {
for (int i = 0; i < arrIndex; i++) {
cout << i << ": " << stringsArr[i] << endl;
}
cout << "\n" << arrCapacity << endl;
}
private:
//ArrIndex shows where the index is at. If it become equal to ArrCapacity (index 2 corresponds to capacity 3, not 2),
// the array needs to be increased in size.
int arrIndex;
int arrCapacity = 0;
string *stringsArr = new string[arrCapacity];
};
StringSet* objectString = new StringSet;
objectString->insert("Dog");
objectString->insert("Cat");
objectString->insert("Turtle");
objectString->insert("Lion");
objectString->insert("Fish");
objectString->insert("Zebra");
objectString->insert("Human");
objectString->insert("Squirrel");
cout << "\n" << endl;
objectString->printStringsArr();
return 0;
}
答案 0 :(得分:1)
将stringsArr
的初始化移动到构造函数体:
StringSet() {
arrCapacity = 4;
arrIndex = 0;
stringsArr = new string[arrCapacity];
}
...
string *stringsArr;
如果没有此更改stringsArr
已初始化为new string[0]
,稍后您的代码会对索引0,1,2和3进行数据索引溢出,从而覆盖堆的其他部分。
更好的是,只要初始化顺序与声明顺序相同:
StringSet(): arrIndex(0), arrCapacity(4), stringsArr(new string[arrCapacity]) {}
也不要在构造函数之外初始化arrCapacity
和arrIndex
。