cout可以改变char数组的内容吗?

时间:2012-04-19 07:48:34

标签: 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)。

请帮忙! 谢谢, 帕特里克:)

编辑:我忘了提到的另一件事是,这种奇怪的行为只发生在第一次执行这段代码时,每次下载时它都会在打印好的程序中运行。

2 个答案:

答案 0 :(得分:3)

这清楚地表明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();

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

答案 1 :(得分:0)

不,cout不会更改参数的内容。

你可能事先做错了,并且遇到了未定义的行为。