С вопросом из интервью - PullRequest
       0

С вопросом из интервью

0 голосов
/ 17 февраля 2011

В каких строках этот код потерпит неудачу (имеется в виду: не делайте то, что они должны делать) и почему?

int main(void) {
 char student[64] = "some guy";
 char* teacher;

 /* line1 */ strcpy(teacher, student);
 /* line2 */ teacher=student;
 /* line3 */ strcpy(student, "Alber Einstein");
 /* line4 */ student = teacher;
}

Ответы [ 6 ]

8 голосов
/ 17 февраля 2011

Вроде шутит, но тоже серьезно:

  • Строка 1 не работает, потому что вы использовали функцию strcpy( ), которая может привести к тому, что копия перезапишет границы целевого буфера, еслипрограммист по техническому обслуживанию увеличивает размер массива student в будущем.Это потенциально может позволить выполнение произвольного кода в некоторых средах и является уязвимостью безопасности.

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

  • Строка 3 завершается сбоем из-за неправильного написания имени Альберта Эйнштейна.

  • Строка 4 не выполняется, посколькуон недействителен C.

Дело в том, что вам нужно иметь спецификацию, прежде чем вы сможете провести содержательное обсуждение того, как программа работает или не дает сбоя.

8 голосов
/ 17 февраля 2011

Строка 1 вызывает неопределенное поведение.Строка 4 даже не скомпилируется.Поскольку кажется, что это так же легко может быть домашним заданием, и я не хотел бы все рассказывать, краткий обзор comp.lang.c FAQ или Cспецификация языка объяснит почему.

2 голосов
/ 18 февраля 2011

В дополнение к тому, что говорили другие:
Если вы используете компилятор C89, строка 5"не удается" (*)

Функция main является специальнойтолько в том, что это функция, вызываемая реализацией при запуске программы.В отличие от C99, он не особенный в том, как он заканчивается.Функция с типом возврата, отличным от void ДОЛЖЕН (в C89 и, за исключением main, в C99), возвращать что-то, чтобы избежать неопределенного поведения.

(*) в C99 есть неявная return 0; прямо перед закрывающей скобкой функции main

2 голосов
/ 17 февраля 2011
strcpy(teacher, student);

Это невозможно, потому что вы не выделили учитель с помощью malloc(). Это указывает на случайное, и будет писать случайное. UB в пути

0 голосов
/ 17 февраля 2011

строка 4 определенно потерпит неудачу, поскольку объявление char student[64] по существу определяет student как постоянный указатель на символ. Назначение пытается изменить значение указателя (а не строки, на которую он указывает), что нарушило бы его постоянный характер.

строка 1 должна вызывать проблемы во время выполнения, но пройдет компилятор (может быть, сгенерировано предупреждение). Так как учить ничего не было назначено (т. Е. Это недопустимый указатель), вы не можете скопировать значение в место, на которое оно указывает, поскольку оно нигде не указывает.

0 голосов
/ 17 февраля 2011

Компилятор пожалуется в / * строку 4 * /. Объявляя студента таким образом, он будет вести себя как постоянный указатель на начальный адрес 64-байтового блока. Он не может быть назначен, хотя на него можно ссылаться (в строках 1 + 2) и иметь память, на которую он указывает (в строке 3).

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