VS2010 C代码 – 字符串池

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

-Karthik

cl.exe /MD /O2 test.c

// Test.c

 #include  #include  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); } 

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

来自ISO C99( Section 6.4.5/6

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

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

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

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

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

  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 } } 

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

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