[英]Resizing char array not always working
在名為Str
的自定義字符串類中,我具有一個函數c_str()
,該函數僅將私有成員char* data
返回為const char* c_str() const { return data; }
const char* c_str() const { return data; }
。 在創建新的Str
后調用此方法有效,但是如果我隨后使用cin
覆蓋Str
,則僅在某些情況下對其調用c_str()
,但如果我將cin
大於原始Str
則始終有效。
Str b("this is b");
cout << b.c_str() << endl;
cin >> b;
cout << b.c_str() << endl;
在這里,第一個b.c_str()
起作用了,但是如果我嘗試將cin >> b;
上的Str b
更改為“ b” cin >> b;
行,然后輸出'b'+一點垃圾。 但是,如果我嘗試將其更改為“ bb”,則通常可以使用,並且如果將其更改為比“ this is b”更長的時間,則它始終可以使用。
這很奇怪,因為我的istream運算符(被友好地使用)完全取消了Str
分配,並最終為讀取的每個char分配了僅大1個char的新char數組(只是為了查看它是否可以工作,不可以)。 因此,似乎在讀取其他內容后返回數組將返回已設置data
的新數組。
相關功能:
istream& operator>>(istream& is, Str& s) {
delete[] s.data;
s.data = nullptr;
s.length = s.limit = 0;
char c;
while (is.get(c) && isspace(c)) ;
if (is) {
do s.push_back(c);
while (is.get(c) && !isspace(c));
if (is)
is.unget();
}
return is;
}
void Str::push_back(char c) {
if (length == limit) {
++limit;
char* newData = new char[limit];
for (size_type i = 0; i != length; ++i)
newData[i] = data[i];
delete[] data;
data = newData;
}
data[length++] = c;
}
使用這樣的push_back()
,該數組的容量將永遠不會超過其擁有的容量,因此我看不到c_str()
如何輸出任何內存垃圾。
基於問題中的push_back()
和注釋中的c_str()
,不能保證從c_str()
返回的C字符串為空終止。 由於char const*
在沒有空終止符的情況下不知道字符串的長度,因此這就是問題的根源!
分配小內存對象時,您可能會找回字符串類先前使用的小內存對象之一,該對象包含非空字符,導致打印的字符看起來好像是找到的第一個空字節的長度一樣。 當分配更大的塊時,您似乎會返回仍然包含空字符的“新”內存,從而使情況看起來好像一切正常。
基本上有兩種方法可以解決此問題:
c_str()
返回char const*
之前,添加一個空終止符。 如果您暫時不關心多線程,可以在c_str()
函數中完成。 在多線程很重要的情況下,對const
成員函數進行任何更改可能是一個壞主意,因為它們會引入數據競爭。 因此,C ++標准字符串類在一個突變操作中添加了空終止符。 c_str()
函數,而是為您的字符串類實現輸出運算符。 這樣,不需要空終止。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.