可以更改字符数组的内容

Can cout change the contents of a char array?

本文关键字:数组 字符      更新时间:2023-10-16

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

    char* aiMove = getAIMove();
    cout << aiMove;
    cout << "n" << numMoves << ": " << aiMove << "nn";
    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();

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

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

您可能事先做错了什么,并遇到了未定义的行为。