c++ - cout 可以更改 char 数组的内容吗?

标签 c++ string formatting char cout

为了尽可能快速和简洁,这是我的代码:

    char* aiMove = getAIMove();
    cout << aiMove;
    cout << "\n" << numMoves << ": " << aiMove << "\n\n";
    return aiMove;

这是我的输出:

    a0 a1
    0: �����������������������7

因此,第一行调用 getAIMove() 并将返回值 (char*) 分配给 aiMove。

第二行打印aiMove(a0 a1)

第三行将 numMoves 和 aiMove 带入 cout 并打印它,但它打印了一些奇怪的值。

第 4 行返回 aiMove,我检查它是打印的奇怪值。

为什么 aiMove 的值发生了变化?它似乎只有在我将整数值传递给 cout(在本例中为 numMoves)时才会发生。

求助! 谢谢, 帕特里克:)

编辑:我忘记提及的另一件事是,这种奇怪的行为只发生在第一次执行此代码块时,每次在程序运行期间它都会正常打印。

最佳答案

这清楚地表明 getAIMove 返回了一个指向系统可以自由重用的内存的指针。来自堆栈或堆的后续分配覆盖了返回的指针。

发生这种情况的方式有很多种,这可能是最常见的:

char *GetAIMove()
{
    char buf[128];
    strcpy(buf, "a0");
    strcat(buf, " ");
    strcat(buf, "a1");
    return buf; // oops, buf won't exist after we return
}

糟糕。此代码返回一个指向缓冲区的指针,该缓冲区在返回后立即消失。此问题的典型解决方法是 return strdup(buf);。请记住,函数的调用者在使用完字符串后需要释放该字符串。

另一种方式:

std::string GetAIMove()
{
 // ...
 return foo;
}

char* aiMov e= GetAIMove();
// aiMove points to the contents of the returned string, no longer in scope.

对此的修复是 std::string aiMove = GetAIMove。现在 aiMove 将字符串保留在范围内。

但最好的解决方法是使用一个专门设计用来保存字符串的字符串类:

std::string GetAIMove()
{
    std::string foo;
    foo = "a1";
    foo += " ";
    foo += "a2";
    return foo;
}

std::string aiMove = GetAIMove();

请注意,虽然此代码似乎涉及大量复制,但在实践中,现代编译器会使其变得高效。因此,不要因为保持代码简单、合乎逻辑、易于理解和维护而感到难过。

关于c++ - cout 可以更改 char 数组的内容吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10223741/

相关文章:

c++ - Windows标题中的侵入性定义

python - 如何覆盖 python 中的默认字符串格式化程序?

python - 相同的抽象语法树是否保证相同的行为?

Ruby跨平台EOF符号的写法

python - 使用 Python 将字符串转换为 Csv 文件

javascript - 如何在 JavaScript 中打印货币格式

c++ - 在 Visual Studio 中放置并插入 unordered_map?

c++ - 遍历字符串并组合每个循环中的前一个字符

c++ - Qt 4.7 和 4.8 之间的 OpenSceneGraph 性能

c - 无法使用 fgets() 函数读取循环结构内的字符串