0

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

    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)时发生。

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

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

4

2 回答 2

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();

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

于 2012-04-19T07:57:50.683 回答
0

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

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

于 2012-04-19T07:57:26.487 回答