@nesterione

О нюансах работы со строками и массивами в C

У меня возник вопрос, на который никак не могу найти конкретный ответ.

Нa языке СИ можно копировать строки:

void strcpy(char *s, char *t)
    {
        while (*s++ = *t++)
        ;
     }


При том строки, понятное дело 's' может быть короче 't', есть ли здесь подводные камни, каким образом будет выделятся память для новых элементов, понятно что я смещаю указатель, но какие ячейки памяти он будет брать.

Если работать с обычным массивом, можно сделать так,

int ar[] = {0,1,2};
      // Мне ничего не мешает сослаться на элемент за приделом массива
      ar[5] = 5;
     // и в таком случае
     printf("%d\n", ar[5]);
     // Выведет значение - 5


Но поскольку я вышел за пределы массива, то, я так понимаю, взял какую-то область памяти, которая могла иметь другие значения и испортил её.

Не происходит ли тоже самое при копировании строк, в первом участке кода, если строка 's' имеет меньшую длину чем 't'?
  • Вопрос задан
  • 4085 просмотров
Решения вопроса 1
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
C - язык со статической типизацией. Это означает, что во время объявления переменной под неё выделяется область памяти, которая в дальнейшем не меняется. Соответственно если происходит выход за пределы этой области, то есть шансы испортить соседние данные, код программы или получить системное исключение при попытке записи за пределы памяти, отведённой программе.
Функция копирования строк есть в стандартной библиотеке string.h и устроена несколько сложнее. Попробуйте с помощью своей функции выполнить следующий код:
char str[20] = "Прпущен символ";
strcpy(str+3, str+2);
str[2] = 'о';
printf("%s\n", str);
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
tsarevfs
@tsarevfs Куратор тега C++
C++ developer
За вас память в си никто не выделяет.
Цитата отсюда:
To avoid overflows, the size of the array pointed by destination shall be long enough to contain the same C string as source (including the terminating null character), and should not overlap in memory with source.
Ответ написан
risik
@risik
Программист
На вопрос Вам уже ответили - Вы и только Вы следите за достаточностью блока памяти. Строки в С почти ничем не отличаются от обычного массива. Разве что нуль символ компилятор ставит автоматически если инициализация строки производится в кавычках.

Пример 1:
char h[20]="Hello";
Выделяется массив из 20-ти элементов char, первые 6 из которых будут заполнены значениями, остальные 14 будут иметь случайные значения.

Пример 2:
char h[20]={'H', 'e', 'l', 'l', 'o'};
Выделяется массив из 20-ти элементов char, первые 5 из которых будут заполнены значениями, остальные 15 будут иметь случайные значения.

Еще хотел обратить Ваше внимание на один момент.
void strcpy(char *s, const char *t)
указатель на char откуда копируете строку следует объявлять константным. В С++ так нужно уже давно. В С уже тоже. Хотя, не знаю с какой версии стандарта.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы