gpt4 book ai didi

c++ - 调整 char 数组的大小并不总是有效

转载 作者:行者123 更新时间:2023-11-28 00:28:05 27 4
gpt4 key购买 nike

在一个名为 Str 的自定义字符串类中,我有一个函数 c_str(),它只返回私有(private)成员 char* data 作为 >const char* c_str() const { 返回数据; }。这在我创建一个新的 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() 有效,但如果我尝试将 Str b 更改为 cin >> b 上的 'b'; 行然后它输出 'b' + 一些垃圾。但是,如果我尝试将其更改为“bb”,它通常会起作用,而如果我将其更改为比“this is b”更长的内容,它总是会起作用。

这很奇怪,因为我的 istream 运算符(它是友好的)完全取消分配 Str 并最终分配一个新的 char 数组,对于它读入的每个 char 只大 1 个 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 字符串() 以 null 结尾。由于 char const* 不知道没有空终止符的字符串的长度,这就是问题的根源!

分配小内存对象时,您可能会取回字符串类之前使用的小内存对象之一,该对象包含非空字符,导致打印字符看起来好像是第一个空字节的长度成立。当分配更大的 block 时,您似乎会取回仍然包含空字符的“新鲜”内存,使情况看起来好像一切正​​常。

基本上有两种方法可以解决这个问题:

  1. 在从 c_str() 返回一个 char const* 之前添加一个空终止符。如果您现在不关心多线程,这可以在 c_str() 函数中完成。在多线程重要的上下文中,在 const 成员函数中进行任何更改可能不是一个好主意,因为这会引入数据竞争。因此,C++ 标准字符串类在其中一个变异操作中添加了空终止符。
  2. 根本不支持 c_str() 函数,而是为您的字符串类实现一个输出运算符。这样,就不需要空终止。

关于c++ - 调整 char 数组的大小并不总是有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24129443/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com