VS2010 C代码 - 字符串池

Kar*_*lee 1 c c++ winapi visual-studio-2010 visual-studio

当您使用以下标志进行编译时,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);  
}  
Run Code Online (Sandbox Code Playgroud)

Pra*_*rav 7

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

来自ISO C99(Section 6.4.5/6)

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

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

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

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


sha*_*oth 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
     }  
 }  
Run Code Online (Sandbox Code Playgroud)

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