C样式的字符串未使用=运算符更新-C ++

时间:2018-10-24 15:43:12

标签: c++

所以最近我正在玩创建自己的代表通用数据(例如字符串,数字和数组)的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 // -> ...

我知道这可能不是问这种性质的问题的平台,但是一点帮助将大有帮助。感谢您通读。

1 个答案:

答案 0 :(得分:6)

globalStringchar*,它指向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字符串很棘手野兽。