我認爲你的代碼比它可能需要更復雜。我會考慮使用std
容器,如std::vector
或更適合您的任何需求。一般來說,除非真的有必要,否則你應該避免多層次的間接尋址,在這種情況下它看起來不是這樣。
理解指針
你開始通過聲明BankTeller **tellers
,這是一個指向指針BankTeller。在您的代碼中導致段錯誤的行是*tellers = new BankTeller[count];
。這一行返回一個指向數組BankTeller
對象的指針,但是你的雙聲道**
的聲明表示它應該得到一個數組指針到BankTeller
對象。分配的值仍然被解釋爲一個地址(它不是),並最終嘗試訪問無效的內存位置,從而觸發段錯誤。
相反它應該是*tellers = new BankTeller*[count];
。請注意開頭括號前的*
。這一行將爲您提供一組指針至BankTeller
對象。
簡單的例子
爲了說明這一點,忘掉BankTeller
S和讓我們回到原語。
#include <iostream>
using namespace std;
int main()
{
const size_t max = 3;
int **nums;
cout << "Creating arrays...";
nums = new int*[max]; // <<---- not: nums = new int[max];
for(size_t i = 0; i < max; ++i)
nums[i] = new int(i);
cout << "done" << endl;
cout << "Contents: ";
for(size_t i = 0; i < max; ++i)
cout << *nums[i] << ' '; // <<---- dereferenced twice to reach actual value
cout << endl;
cout << "Deleting arrays...";
for(size_t i = 0; i < max; ++i)
delete nums[i];
delete[] nums;
cout << "done" << endl;
return 0;
}
請注意,這與前面介紹的情況相同。要運行它,將代碼放在一個名爲test.cpp
文件,並使用這個(GNU/Linux)的命令:如果你想要去在它在調試器中,加入-ggdb
到g++
以上命令,以確保
➜ /tmp g++ test.cpp -o test && ./test
Creating arrays...done
Contents: 0 1 2
Deleting arrays...done
➜ /tmp
您將調試符號添加到二進制文件。然後,您可以使用b <linenumber>
(例如b 10
)設置斷點,並使用p <variable_name>
(例如p nums
,p *nums
等)來打印地址和值。
但是,你不需要像這樣使用原始指針。您可以也應該使用標準模板庫中的容器。
你的代碼重構
我重新寫下面的示例代碼,使用std::vector
代替雙指針。
#include <iostream>
#include <vector>
using namespace std;
class BankTeller
{
public:
BankTeller() {
cout << "Created BankTeller\n";
}
~BankTeller() {
cout << "Destroyed BankTeller\n";
}
};
class BankModel
{
public:
BankModel(size_t count) {
// remember to throw exception if count <= 0
for(size_t i = 0; i < count; ++i)
_tellers.push_back(new BankTeller());
cout << "Created BankModel\n";
}
~BankModel() {
// consider using iterators
for(size_t i = 0; i < _tellers.size(); ++i) {
delete _tellers[i];
_tellers[i] = 0;
}
_tellers.clear();
cout << "Destroyed BankModel\n";
}
private:
vector<BankTeller*> _tellers;
};
int main() {
BankModel *model = new BankModel(5);
delete model;
return 0;
}
大廈和在我的系統(GNU/Linux)的運行,它看起來如下:
➜ /tmp g++ tellers.cpp -o tellers
➜ /tmp ./tellers
Created BankTeller
Created BankTeller
Created BankTeller
Created BankTeller
Created BankTeller
Created BankModel
Destroyed BankTeller
Destroyed BankTeller
Destroyed BankTeller
Destroyed BankTeller
Destroyed BankTeller
Destroyed BankModel
希望這可以幫助您瞭解這兩個指針,並使用STL的好處。
來源
2015-10-09 21:21:08
ray
有沒有任何回覆完全回答你的問題?如果是這樣,請務必將其中一個標記爲已接受,以向更廣泛的社區表明您獲得了所需的內容。如果不是,那麼請務必澄清並解釋可能仍不清楚的事情。 – ray