2012-04-19 46 views
0

为了节省您的时间和简洁越好,这是我的代码:cout可以更改char数组的内容吗?

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

and getAIMove()is char * getAIMove(){char str [] =“Patrick”;返回str; } ???如果是,那么返回指向局部变量的指针是错误的。 – Jagannath 2012-04-19 07:50:24

+5

你能提供getAIMove()的代码吗?你是否返回一个本地堆栈分配变量? – 2012-04-19 07:50:47

+0

@Jagannath你是对的,getAIMove()最终返回char str []。谢谢:)虽然我仍然不明白为什么传递一个整数值给cout会产生影响:S – 2012-04-19 08:00:24

回答

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

注意的是,虽然该代码似乎涉及了很多复制的,在实践中,现代的编译器会使其高效。所以,不要让你的代码简单,合理,易于理解和维护。

+0

感谢您的深入解释! :)是否可以使getAIMove()返回一个std :: string然后这样做:char * aiMove = getAIMove()。c_str(); ? – 2012-04-19 08:02:53

+0

否。因为在字符串上调用的任何非const方法使返回的指针无效,并且析构函数为非const。所以再次'aiMove'将指向不再存在的内容。从[c_str](http://www.cplusplus.com/reference/string/string/c_str/)返回的指针仅在可以修改字符串的任何操作之前有效。摧毁它绝对符合资格! – 2012-04-19 08:07:44

0

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

您可能预先做了错误的事情,并且遇到未定义的行为。

相关问题