这段代码有效,还是编译器?

时间:2010-02-18 14:13:37

标签: c++

int cpu = 0;
int player = 0;

char * getPoints()
{
    using namespace std;
    string str = "You: ";
    str += player;
    str += " CPU: ";
    str += cpu;
    char c [100];
    strcpy(c, str.c_str());
    return c;
}

此代码无法编译。代码是错误的还是我的编译器有问题?

我正在Microsoft Visual Studio使用DarkGDK

如果是我,有人可以改善吗?


这是输出:

1>------ Build started: Project: Pong, Configuration: Debug Win32 ------
1>Compiling...
1>Main.cpp
1>c:\users\martijn\documents\visual studio 2008\projects\pong\pong\main.cpp(42) : warning C4172: returning address of local variable or temporary
1>Linking...
1>libcpmtd.lib(xdebug.obj) : warning LNK4098: defaultlib 'libcmt.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
1>libcpmtd.lib(xdebug.obj) : error LNK2019: unresolved external symbol __malloc_dbg referenced in function "void * __cdecl operator new(unsigned int,struct std::_DebugHeapTag_t const &,char *,int)" (??2@YAPAXIABU_DebugHeapTag_t@std@@PADH@Z)
1>libcpmtd.lib(xdebug.obj) : error LNK2019: unresolved external symbol __free_dbg referenced in function "void __cdecl operator delete(void *,struct std::_DebugHeapTag_t const &,char *,int)" (??3@YAXPAXABU_DebugHeapTag_t@std@@PADH@Z)
1>libcpmtd.lib(stdthrow.obj) : error LNK2019: unresolved external symbol __CrtDbgReportW referenced in function "void __cdecl std::_Debug_message(wchar_t const *,wchar_t const *,unsigned int)" (?_Debug_message@std@@YAXPB_W0I@Z)
1>Debug\Pong.exe : fatal error LNK1120: 3 unresolved externals
1>Build log was saved at "file://c:\Users\Martijn\Documents\Visual Studio 2008\Projects\Pong\Pong\Debug\BuildLog.htm"
1>Pong - 4 error(s), 2 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

4 个答案:

答案 0 :(得分:6)

LNK4098错误表示您的构建混合了使用DEBUG设置(因此使用libcmtd.lib)编译的代码和使用非DEBUG设置编译的代码(因此使用libcmt.lib)。

OR:可能是使用动态运行时库(msvcrt.lib)将静态运行时库(libcmt.lib)与代码混合使用的代码。

然后,链接器找到两个不同版本的公共运行时库方法/类,并且无法确定要使用哪个。您不能在一个构建中混合多个运行时库。

在任何一种情况下,这都是解决方案/项目设置问题。当我们尝试链接其他人提供的libs / dll时,我们遇到了这种情况,他们用不同的设置构建它们。

/ NODEFAULTLIB参数(在VS链接器选项下可用作“忽略库”或类似命令)允许您强制忽略一个或多个运行时库集,只留下一个运行时库集。

答案 1 :(得分:4)

错误似乎来自编译器的问题。您确定已正确设置项目吗?

关于返回局部变量的警告很严重。您在函数中的堆栈上分配c数组。当函数返回时,数组将从堆栈中消失,返回的指针最终指向垃圾。请考虑返回string,或在堆上分配c

答案 2 :(得分:4)

你正在做的串联不符合你的想法; std :: string的+ =运算符只接受std :: string,char *或char,所以你试图追加的int会被转换为chars,所以每个都被认为是一个要附加到的字符的ASCII字符字符串。如果你想从许多不同类型的变量构建字符串,你应该考虑使用字符串流(sstream标题)或增强强制转换。

此外,你正在返回一个指向本地对象的指针,当函数返回时它将消失,因此调用者将有一个指向垃圾的指针;如果它在函数返回之后使用它可能出现,因为堆栈的那部分可能还没有被覆盖,但是你处于未定义行为的范围内,如果它处于未定义行为的范围内,它将很难失败你将尝试在另一个函数调用之后使用该指针。

您需要返回一个std :: string,因此调用者将获得自己的字符串副本。然后,如果它需要一个C字符串(ASCIIZ),它将能够从调用c_str()方法的std :: string中获取它。

您发布的错误与链接器有关;当您链接到使用不同版本的CRT编译的静态库时,通常会出现这种错误;要解决此问题,请使用相同版本的CRT重新编译项目和库。

答案 3 :(得分:2)

Martjin,

您的代码有一些错误,一旦运行就会导致程序崩溃。但是,它们都没有阻止你编译/链接它。正如Dirkgently所述,问题在于链接器而不是编译器,这意味着您的代码正确生成了一个对象,但是当VS尝试创建可执行文件时,它找不到必要的符号。

您应该查看SDK文档,以了解如何正确地将对象与其库链接。完成后,应解析所有未定义的外部,这将使您能够创建可执行文件。