所以最近我正在使用创建我自己的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;
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试了所有我能用的代码(是的,使用std::stringfor文本值被禁止).如果有人在那里可以解释为什么在使用时使用多个参数会出错char*,欢迎您发表评论.
总而言之,我需要能够使用可变数量的参数创建String具有适当value属性的对象.
// Works fine
String("Hello, World!").value // -> Hello, World!
// Needs fixing
String("Hello,", ' ', "World!").value // -> ...
Run Code Online (Sandbox Code Playgroud)
我知道这可能不是提出这种性质问题的平台,但是一点帮助会有很长的路要走.感谢您的阅读.
globalString是char*指回归的价值stringify("");.
stringify("")回报strdup(std::string(string).c_str());.strdup返回一个动态分配的字符串,该字符串具有其参数的长度(以及相同的内容).
这里""只包含\0所以返回的C字符串strdup只有一个长度1.
然后,您尝试调用strcat(destination, source)与globalString作为目标,但globalString不是大到足以适应source.
strcat 说:
如果目标数组不足以容纳src和dest的内容以及终止空字符,则行为是未定义的.如果字符串重叠,则行为未定义.如果dest或src不是指向以null结尾的字节字符串的指针,则行为是未定义的.
所以你的两个测试用例都是UB.即使是第一个似乎运作良好的测试.
std::string为您处理所有这些.如果你某种方式不允许将它用于教授给你的任何(愚蠢)理由,那么确保globalString在调用strcat它之前分配足够的空间,C字符串是棘手的野兽.
| 归档时间: |
|
| 查看次数: |
93 次 |
| 最近记录: |