Почему это работает в массивах символов c ++ [duplicate]

0

У меня есть следующий код:

    char arr[6] = "Hello";
    strcpy(arr, "Hello mellow");
    cout << strlen(arr) << ", " << arr << endl; // 12, Hello mellow


    char arr1[] = "Hello";
    strcpy(arr1, "Hello mellow");
    cout << strlen(arr1) << ", " << arr1 << endl; // 12, Hello mellow

Итак, почему это работает? Почему это не ограничивается? Что бы я ни поставил вместо "Hello mellow", он работает и распечатывает его.

  • 2
    иногда это работает, но также может не сработать или даже вызвать сбой программы.
  • 1
    Вам повезло (или нет).
Показать ещё 1 комментарий
Теги:
arrays
char

4 ответа

4
Лучший ответ

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

  • 0
    Ну, большинство современных (всех?) ОС не будут зависать при этом.
  • 0
    @BartFriederichs Наверное, нет. Я не очень знаком с внутренней работой.
Показать ещё 3 комментария
4

В общем случае C и C++ не проверяют границы (в отличие от других языков более высокого уровня: Java, PHP, Python, Javascript и т.д.).

Это означает, что если вы попытаетесь сделать strcopy, скажем, 13- strcopy строкой, такой как "Hello mellow" для массива символов, она не будет проверять, был ли данный массив создан с достаточной памятью, чтобы содержать строку. Он просто скопирует данную строку, символ по символу, в указанный указатель памяти.

Что здесь происходит, так это то, что вы пишете в некоторых местах в памяти, к которым вы не должны обращаться; время от времени, эта программа может просто сбой, без каких-либо других признаков, чем: segmentation fault.

Если вы попытаетесь это сделать...

char arr1[8];
char arr2[8];
strcpy(arr1,"Hello mellow");
printf("%s\n", arr1);
printf("%s\n", arr2);

... это очень вероятно (но не на 100%, см. комментарии), вы получите следующий результат:

Hello mellow
llow

Зачем? Поскольку второй char[] был бы перезаписан данными, которые вы пытались поместить в первый, без наличия достаточного количества зарезервированного пространства для него.

См.: http://en.wikipedia.org/wiki/Stack_buffer_overflow

  • 0
    Почему вы упоминаете переполнение стека?
  • 0
    или любой другой выход, потому что это UB
Показать ещё 3 комментария
1

Собственные массивы в C/C++ представляют собой абстракции низкого уровня, которые во многих случаях рассматриваются как указатели на ячейки памяти. Таким образом, при передаче arr на strcpy все strcpy знает адрес arr[0]. В результате нет возможности проверки границ. Это очень хорошо по соображениям производительности. Программист должен гарантировать, что он/она использует эти низкоуровневые конструкции безопасно, например, используя strncpy и давая соответствующую границу, или используя std::vector и проверяя границы в явном виде или используя std::vector::at проверке границ при доступе к местоположению.

0

Я думаю, что, поскольку нет проверки времени выполнения или времени компиляции, и если вы Lucky, вы не получите ошибку сегментации;)

  • 5
    Не повезло, чтобы не получить ошибку сегментации на мой взгляд.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню