打印自定义字符串数据时的奇怪输出(c ++新手)
Posted
技术标签:
【中文标题】打印自定义字符串数据时的奇怪输出(c ++新手)【英文标题】:weird output when printing data of custom string (c++ newbie) 【发布时间】:2012-01-17 05:17:29 【问题描述】:我主要关心的是我是否安全、高效地执行此操作,并且大部分情况下是否正确。
我需要一些帮助来编写字符串类的实现。也许有人可以帮助我解决我想知道的问题?
我正在尝试编写自己的字符串类来扩展功能和学习目的。我不会用它来代替 std::string 因为这可能是危险的。 :-P
当我使用 std::cout 打印出我的字符串的内容时,我得到了一些意想不到的输出,我想我知道为什么,但我不太确定。我把它缩小到我的分配函数,因为我在字符串中存储字符的任何其他方式都很好。这是我的分配功能:
void String::assign(const String &s)
unsigned bytes = s.length() + 1;
// if there is enough unused space for this assignment
if (res_ >= bytes)
strncpy(data_, s.c_str(), s.length()); // use that space
res_ -= bytes;
else
// allocate enough space for this assignment
data_ = new char[bytes];
strcpy(data_, s.c_str()); // copy over
len_ = s.length(); // optimize the length
我有一个构造函数,它为 char ptr 分配和保存固定数量的字节。它是这样声明的:
explicit String(unsigned /*rbytes*/);
res_ 变量只记录传入的字节数并存储它。这是 string.cpp 中的构造函数代码:
String::String(unsigned rbytes)
data_ = new char[rbytes];
len_ = 0;
res_ = rbytes;
我认为使用这种方法会比为字符串分配新空间更有效。所以当我声明一个新字符串时,我可以使用我最初保留的任何间隔。这是我测试它是否有效的方法:
#include <iostream>
#include "./string.hpp"
int main(int argc, char **argv)
winks::String s2(winks::String::to_string("hello"));
winks::String s(10);
std::cout << s2.c_str() << "\n" << std::endl;
std::cout << s.unused() << std::endl;
std::cout << s.c_str() << std::endl;
std::cout << s.length() << std::endl;
s.assign(winks::String::to_string("hello")); // Assign s to "hello".
std::cout << s.unused() << std::endl;
std::cout << s.c_str() << std::endl;
std::cout << s.length() << std::endl;
std::cout.flush();
std::cin.ignore();
return 0;
如果您担心 winks::String::to_string,我只是将 char ptr 转换为我的字符串对象,如下所示:
String String::to_string(const char *c_s)
String temp = c_s;
return temp;
然而,我在这个方法中使用的构造函数是私有的,所以我强迫自己使用 to_string。到目前为止,我对此没有任何问题。我这样做的原因是为了避免重写不同参数的方法,即:char * 和 String
私有构造函数的代码:
String::String(const char *c_s)
unsigned t_len = strlen(c_s);
data_ = new char[t_len + 1];
len_ = t_len;
res_ = 0;
strcpy(data_, c_s);
非常感谢所有帮助。如果我没有提供有效数量的信息,请告诉我您想知道的内容,我很乐意编辑我的帖子。
编辑:我没有发布完整的 string.hpp 和 string.cpp 的原因是因为它相当大,我不确定你们是否愿意。
【问题讨论】:
您在String::assign
中存在内存泄漏。
怎么样?我正在检查是否有足够的预留空间用于分配。我可能做错了。你能详细说明一下吗?
在else
部分中,您不会在分配之前删除现有的data_
。所以你泄露了旧的内容。
在assign()
中,您没有复制'\0'
字符。
strncpy(data_, s.c_str(), s.length()); // use that space
这不会保存 '\0'
字符。以下是正确的strncpy(data_, s.c_str(), s.length()+1); // use that space
【参考方案1】:
您必须决定是否始终在内部存储以 0 结尾的字符串。如果您不使用终止零字节存储字符串,则您的 c_str
函数必须添加一个。否则,它不会返回 C 字符串。
您的 assign
函数不会 0 终止。所以要么它坏了,要么你不打算 0 终止。如果是前者,修复它。如果是后者,请检查您的 c_str
函数以确保它在末尾放置一个 0。
【讨论】:
以上是关于打印自定义字符串数据时的奇怪输出(c ++新手)的主要内容,如果未能解决你的问题,请参考以下文章