2011-09-12 36 views
1

我在我的项目中有以下代码。变量损坏C++字符串Visual Studio 2005

g(const string& str) 
{ 
    printf("%s", str.c_str()); 
} 

f() 
{ 
    string str("whatever"); 

    g(str); 
} 

它是非常大的代码的一部分。 g()在dll中并且api被导出。 f()是可执行文件的一部分。此代码用于正常工作。但是现在它只适用于调试配置而不是发布配置。我试图调试,发现只要我敲击g()str内容的第一条语句就会消失。所以它打印出null。

发行配置没有改变。

请帮忙。

最好的问候, 希夫

+1

投票结束:您应该尝试减少原始代码,直到您意识到失败。这个问题不能回答,因为发布的代码没有表现出行为。答案是你的代码中某处存在某些问题,但这并不具有建设性。注意(这可能是问题),如果你用不同的标志进行编译,主程序和dll的STL定义可能会有所不同,这将导致违反ODR和未定义的行为。 –

+0

这听起来像一个构建问题(可能与链接器有关)。我的建议是:(1)彻底重建; (2)确保DLL和主程序都是在发布模式下构建的; (3)确保在运行主程序时总是选取正确的DLL; (4)即使你说发布配置没有改变,仔细检查这是事实。 – NPE

回答

2

野生瞎猜:

你编译的DLL,并与不同的编译器标志的程序,并在差异STL的实现是不同的(也许你在一个中使用选中的迭代器,但不在另一个中)。这是违反ODR并会导致未定义的行为。

基本上,一端会创建它的对象版本,并将引用传递给另一端,但另一端会尝试以不同方式解释内存。

如果是这种情况,你应该能够确定调用者和被调用者中字符串的地址是相同的,并且该地址中的内存具有相同的位模式,它的值为sizeof(std::string)调用代码。如果是这种情况,并且两端都以不同的方式解释字符串,则会出现ODR违例。使用相同的确切编译器标志重新编译所有项目。

有两种定义的另一个提示是sizeof(std::string)的值在主程序和DLL(或不同的DLL)中有所不同。如果大小不同,则会告诉您存在ODR违规。大小相同不能用来断言ODR未被违反:它们可能是具有相同大小的不同定义。

+0

这很可能。请注意,可以使用Dependency Walker(http://www.dependencywalker.com/)查看不同DLL所使用的运行时间。 (Doens't与静态链接的东西虽然工作。) – Macke