ARM 上的不同 C++ 输出

Kur*_*han 2 c++

我正在学习C++。我有一台 MacBook Pro M1PRO 芯片和一台配备 Fedora 39 的第 8 代 i5 的华硕。

我了解一点 Java,所以在我的 Hello World 项目中,我尝试重新创建分割和修剪函数,但在 C+ 中,我发现一些非常令人费解的东西。

我在两台机器上使用以下命令进行编译: g++ -std=c++20 -o hello main.cpp

代码:

#include <iostream>
#include <vector>

using std::cout;
using std::endl;
using std::string;
using std::vector;


string vector_to_string(const vector<string>& v, const string& separator = "") {
    string result = "[";
    for (size_t i = 0; i < v.size(); ++i) {
        result += v[i];
        if (i < v.size() - 1) {
            result += separator;
        }
    }
    result += "]";
    return result;
}

string trim(const string& input) {
    if (input.empty()) {
        return "";
    }

    constexpr char SPACE = ' ';
    const size_t first_index = input.find_first_not_of(&SPACE);
    if (first_index == string::npos) {
        return "";
    }
    const size_t last_index = input.find_last_not_of(&SPACE);

    return input.substr(first_index, last_index - first_index + 1);
}

vector<string> split(const string& input, const char delimiter) {
    vector<string> tokens;

    size_t last_start = 0;
    for(size_t i = 0; i < input.length(); i++) {
        if (input[i] == delimiter) {
            string token = trim(input.substr(last_start, i - last_start));
            if (!token.empty()) {
                tokens.push_back(token);
            }
            last_start = i + 1;
        }
    }
    string lastToken = trim(input.substr(last_start));
    if (!lastToken.empty()) {
        tokens.push_back(lastToken);
    }

    return tokens;
}

int main() {
    const string input = "Hello world";
    const vector<string> tokens = split(input, ' ');
    cout << vector_to_string(tokens, ", ") << endl;
    return 0;
    
}
Run Code Online (Sandbox Code Playgroud)

所以我期待一个 [Hello, world] 输出,它确实在我的 Linux 机器上完美地发生。但在 Mac 上,每次执行输出程序时,我要么得到正确的 [Hello, world],要么得到不正确的 [Hell, world]。

这可能是一个地狱般的世界,但我非常想了解为什么会发生这种情况。我的想法是我的 Mac 上的编译器有问题,或者 ARM 工作得很奇怪,但我对此表示怀疑。

另外,请随时纠正我的代码并评判我,这有助于我学习。

谢谢!

尝试将CPU换成intel,效果很好。尝试谷歌搜索,找不到任何具体内容。尝试询问 ChatGPT 但它不知道如何回答。

Nat*_*ica 6

你的问题是

constexpr char SPACE = ' ';
const size_t first_index = input.find_first_not_of(&SPACE);
Run Code Online (Sandbox Code Playgroud)

函数内部trimfind_first_not_of需要一个 c 字符串或 astd::string作为输入。 &SPACE不是一个 C 字符串,因为它不是以 null 结尾的。这使得您的程序具有未定义的行为,以及为什么您每次运行都会得到不同的结果。

要解决这个问题,只需使用const std::string类似的

const std::string SPACE = " ";
const size_t first_index = input.find_first_not_of(SPACE);
Run Code Online (Sandbox Code Playgroud)

您还需要修复

const size_t last_index = input.find_last_not_of(&SPACE);
Run Code Online (Sandbox Code Playgroud)

使用上述建议将其变成

const size_t last_index = input.find_last_not_of(SPACE);
Run Code Online (Sandbox Code Playgroud)

正如评论中的heap underrun所指出的,还有一个只需要单个字符的重载,可以像这样使用

constexpr char SPACE = ' ';
const size_t first_index = input.find_first_not_of(SPACE);
...
const size_t last_index = input.find_last_not_of(SPACE);
Run Code Online (Sandbox Code Playgroud)

  • 另一种选择:保留 `constexpr char SPACE = ' ';` 不变,但使用采用单个字符的重载:`find_first_not_of(SPACE)`。 (2认同)