Я поддерживаю код C, который делает что-то вроде этого:
char *foo = "hello"
int i;
char *bar;
i = strlen(foo);
bar = &foo[i];
Это безопасно?
Представленный код соответствует текущему и всему прошломуСтандарты языка C, и имеет то же четко определенное поведение в соответствии с каждым.В частности, имейте в виду, что строковые литералы C представляют символьные массивы с нулевым символом в конце, как и все остальные строки C, как в примере кода.foo[i]
относится к терминатору, а &foo[i]
указывает на массив (до его последнего элемента), а не за его пределами.
Кроме того, C также позволяет получить указатель на только что прошедшиеконец массива, поэтому даже 1 + &foo[i]
является действительным и соответствующим.Разрешается разыменовывать такой указатель, но вы можете выполнять арифметику указателей и сравнивать их (при условии соблюдения обычных ограничений).
Может ли быть случай, когда foo [i] приводит кошибка сегментации, до того, как она получит указатель и не будет покрыта компилятором?
C не имеет ничего общего с ошибками сегментации.Всякий раз, когда вы его получаете, либо ваша реализация демонстрирует несоответствие, либо (почти всегда) ваша программа выполняет неопределенное поведение.Представленный код соответствует, при условии правильной декларации strlen()
, находящейся в области видимости, и если он появляется как часть полной программы, которая соответствует и не использует UB, то нет никаких оснований, кроме общего скептицизма, бояться ошибки сегмента.