为了使此操作尽可能简洁明了,这是我的代码:

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


请注意,尽管此代码似乎涉及大量复制,但实际上,现代编译器将使其高效。因此,让您的代码保持简单,逻辑性,易于理解和维护,不会感到不好。

10-08 08:14