Код VS2010 C - Объединение строк - PullRequest
1 голос
/ 20 июля 2010

Ниже происходит сбой кода в VS 2010, когда вы компилируете со следующим флагом и если вы добавляете / GF- или снимаете флаг оптимизации, они не терпят крах. Сбой происходит в коде сборки, который переводится как 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 ]

7 голосов
/ 20 июля 2010

Попытка изменить содержимое string literal вызывает неопределенное поведение.

Из ISO C99 (Section 6.4.5/6)

Не определено, различаются ли эти массивы, еслиэлементы имеют соответствующие значения. Если программа пытается изменить такой массив, поведение не определено

Из ISO C ++ - 98 (Section 2.13.4/2)

Все лиСтроковые литералы различны (то есть хранятся в неперекрывающихся объектах) в зависимости от реализации. Эффект попытки изменить строковый литерал не определен.

В большинстве реализаций (включая MSVC) это приводит к сбою приложения.

5 голосов
/ 20 июля 2010

Вы пытаетесь изменить строковый литерал, это неопределенное поведение.

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

строковые литералы обычно хранятся в постоянной памяти, поэтому в вашей реализации попытка изменить строковый литерал приводит к нарушению доступа, что приводит к сбою вашей программы.

0 голосов
/ 14 января 2016

У нас есть приложение, в котором в VC6.0 появляется ошибка в пуле строк. Две разные строки «объединяются» в одну строку, вызывая сбой. Этот сбой не происходит в VS2010. ИЛИ, если в VS6.0 используется / Zi вместо / ZI. Просто интересно, по умолчанию в VS6.0 используется пул строк, а не по умолчанию в VS2010. В этом случае может случиться так, что ошибка объединения строк все еще существует. Если существует МНОГИЕ строки, которые почти идентичны, рабочая теория, которую я имею (еще предстоит проверить), заключается в том, что в пуле строк происходит столкновение хеша, которое остается необнаруженным, что исключает одну из двух строк. Это будет видно в сгенерированном коде ASM, если взглянуть на указатели на две почти одинаковые строки. В нашем случае мы не изменяем строки в VC6.0, просто ссылаемся на них.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...