所以最近我正在玩创建自己的代表通用数据(例如字符串,数字和数组)的C ++类的概念。
到目前为止,我在这方面的进展一直不错(如此处:https://github.com/LapysDev/LapysCPP)。
除了一个结。为了我的一生,我无法弄清楚为什么下面的代码在创建带有可变数量参数的String
类对象时会出错。
#include <iostream>
#include <sstream>
#include <string.h>
// Make a new C-style string (or stringify a value).
char* stringify(char character) {
std::string stream = static_cast<std::ostringstream*>(&(std::ostringstream() << character)) -> str();
char* string = new char[stream.size() + 1];
strcpy(string, stream.c_str());
return string;
}
template <typename data> char* stringify(data string) { return strdup(std::string(string).c_str()); }
char* globalString = stringify("");
class String {
public:
char* value = stringify("");
String() {}
template <typename data>
String(data value) {
strcat(globalString, value);
this -> value = stringify(globalString);
globalString = stringify("");
}
template <typename data, typename... argumentsData>
String(data value, argumentsData... values) {
strcat(globalString, stringify(value));
String(values...);
}
};
int main(int argc, char* argv[]) {
std::cout << "String [1]: '" << String("Hello, World!").value << '\'' << std::endl;
// -> String [1]: 'Hello, World!'
std::cout << "String [3]: '" << String("Hello,", ' ', "World!").value << '\'';
// -> String [3]: ''
return 0;
}
我已经尝试了使用代码的所有方法(是的,禁止使用std::string
作为文本值)。如果有人可以解释为什么在使用char*
时使用多个参数会出错,那么欢迎发表评论。
总而言之,我需要能够使用数量可变的参数来创建具有适当的String
属性的value
对象。
// Works fine
String("Hello, World!").value // -> Hello, World!
// Needs fixing
String("Hello,", ' ', "World!").value // -> ...
我知道这可能不是问这种性质的问题的平台,但是一点帮助将大有帮助。感谢您通读。
答案 0 :(得分:6)
globalString
是char*
,它指向stringify("");
的返回值。
stringify("")
返回strdup(std::string(string).c_str());
。 strdup
返回一个动态分配的字符串,该字符串具有其参数的长度(和相同的内容)。
此处,""
仅包含\0
,因此从strdup
返回的C字符串的长度仅为1
。
然后,您尝试以strcat(destination, source)
作为目的地呼叫globalString
,但是globalString
的容量不足以容纳source
。
strcat
说:
如果目标数组不大,则行为未定义 足以容纳src和dest的内容以及终止null 字符。如果字符串重叠,则行为未定义。的 如果dest或src不是指向a的指针,则行为未定义 空终止的字节字符串。
因此,您的两个测试用例都是UB。即使是第一个似乎工作正常的测试。
std::string
为您处理所有这一切。如果由于某种原因(教授)给您某种原因而不允许您使用它,那么请确保在调用globalString
之前为strcat
分配足够的空间,C字符串很棘手野兽。