VS2010 C代码 - 字符串池

时间:2010-07-20 05:01:01

标签: c++ c visual-studio visual-studio-2010 winapi

使用以下标志编译时,VS 2010中的代码崩溃,如果添加/ GF-或删除opimization标志,则不会崩溃。崩溃发生在汇编代码中,该代码转换为'if(path [i] =='/')'。我喜欢理解编译器在这里做的优化并导致崩溃。期待一些指示。

-Karthik

cl.exe /MD /O2 test.c

// Test.c

#include <stdio.h>

#include  <string.h>

void testpath(char* path, int bufsiz)  
{  

    int i;  

    printf("%p\n", path);  
    for( i=0; i < strlen(path); i++ ) {  
      if( path[i] == '/' ) {  
         path[i] = '\\';  
     }  
  }  
}

int main()  
{  

    const char* path = "testexport.prj";  
    char *path1 = "testexport.prj";  
    printf("%p\n", path);  
    printf("%p\n", path1);  
    testpath(path, 1024);  
}  

3 个答案:

答案 0 :(得分:7)

尝试修改string literal的内容会调用未定义的行为。

来自ISO C99(Section 6.4.5/6

  

如果这些数组的元素具有适当的值,则这些数组是否不同是不明确的。 如果程序试图修改此类数组,则行为未定义

来自ISO C ++ - 98(Section 2.13.4/2

  

是否所有字符串文字都是不同的(即存储在非重叠对象中)是实现定义的。 尝试修改字符串文字的效果未定义。

在大多数实现(包括MSVC)上,这会导致应用程序崩溃。

答案 1 :(得分:5)

您尝试修改字符串文字,这是未定义的行为。

 const char* path = "testexport.prj";
 testpath(path, 1024);
 // then later:
 void testpath(char* path, int bufsiz)
 {
     int i;  
     for( i=0; i`<`strlen(path); i++ ) {  
     if( path[i] == '/' ) {  
         path[i] = '\\';// <<<<<< UB here
     }  
 }  

字符串文字通常存储在只读内存中,因此在您的实现中,尝试修改字符串文字会导致访问冲突,从而导致程序崩溃。

答案 2 :(得分:-1)

我们有一个应用程序,在VC6.0中似乎存在字符串池中的错误。两个不同的字符串出现在&#34; pool&#34;到一个字符串,导致崩溃。 VS2010中不会发生此崩溃。或者如果在VS6.0中使用/ Zi而不是/ ZI。只是想知道VS6.0中的默认值是使用字符串池而不是VS2010中的默认值。在这种情况下,字符串池错误可能仍然存在。如果有许多字符串几乎相同,我所拥有的工作理论(尚未审查)是在字符串池中未检测到哈希冲突,这消除了两个字符串中的一个。当查看两个几乎相似的字符串的指针时,这将在生成的ASM代码中可见。 在我们的例子中,我们不是在VC6.0中修改字符串,只是引用它们。