825 просмотров
От 4 июня

Ответы на вопросы для собеседования по C

1

Какого типа значение возвращает main()?

Скомпилируется ли следующий код? Если да, то какие проблемы могут возникнуть? #include <stdio.h> void main(void) { char *ptr = (char*)malloc(10); if(NULL == ptr) { printf("\n Malloc failed \n"); return; } else { // Do some processing free(ptr); } return; } Этот код скомпилируется без ошибок, но с варнингом (на большинстве компиляторов) о том, что значение, возвращаемое функцией main(), должно иметь тип int, а не void. Тип int позволяет программам возвращать код статуса, что очень важно, когда программа выполняется как часть скрипта, и внутри скрипта есть условия, которые зависят от результата выполнения программы.

2

Что такое указатель?

Указатель — это переменная, которая хранит адрес памяти объекта. Указатели широко используются в C и C++, например, в подобных случаях: 1. Для выделения новых объектов в куче, 2. Для передачи функций другим функциям 3. Для итерации элементов в массивах или других структурах данных.

3

Различия sprintf() и printf()?

Метод sprint() работает аналогично методу printf() за исключением одной небольшой детали. Метод printf() записывает вывод на экран консоли, тогда как метод sprintf() записывает вывод в массив символов.

4

Расскажите про порядок аргументов printf()

#include <stdio.h> int main(void) { int a = 10, b = 20, c = 30; printf("\n %d..%d..%d \n", a+b+c, (b = b*2), (c = c*2)); return 0; } Вопрос: Что выведет данный код? Ответ: Программа выведет следующее: 110..40..60 Несмотря на то, что аргументы функции printf отображаются слева направо, вычисляются они справа налево. Однако, порядок вычисления аргументов стандартом не определен. Аргументы кладутся в стек справа налево, но порядок их вычисления может быть иным. В Java, например, такой проблемы нет.

5

Расскажите про функцию gets()

В приведенной программе есть проблема. Можете её найти? #include <stdio.h> int main(void) { char buff[10]; memset(buff,0,sizeof(buff)); gets(buff); printf("\n The buffer entered is [%s]\n",buff); return 0; } Скрытая проблема в этом коде – это использование функции gets(). Эта функция принимает строку со стандартного ввода без проверки размера буфера, в который будет помещена эта строка. Это запросто может привести к переполнению буфера. В данном случае лучше использовать другую стандартную функцию – fgets(). Дополнение: gets() является deprecated.

6

Расскажите про функцию strcpy()

Приведенный код реализует простейшую защиту по паролю. Можно ли вы взломать эту защиту, не зная пароля? #include <stdio.h> int main(int argc, char *argv[]) { int flag = 0; char passwd[10]; memset(passwd,0,sizeof(passwd)); strcpy(passwd, argv[1]); if(0 == strcmp("LinuxGeek", passwd)) { flag = 1; } if(flag) { printf("\n Password cracked \n"); } else { printf("\n Incorrect passwd \n"); } return 0; } Логику кода аутентификации, приведенного выше, можно обойти при помощи уязвимости в функции strcpy(). Эта функция копирует пароль, предоставленный пользователем, в буфер ‘passwd’, не проверяя, достаточно ли в этом буфере места. Предположим, что пользователь введет случайный пароль, имеющий длину, достаточную для того, чтобы заполнить как буфер ‘passwd’, так и перезаписать область памяти, содержащую изначальное значение 0 переменной flag. В этом случае, даже если сравнение введенной строки и пароля не пройдет, то все равно проверка флага, который изначально имел нулевое значение, станет ненулевым, и таким образом, защита будет “взломана”. К примеру: $ ./psswd aaaaaaaaaaaaa Password cracked Здесь можно видеть, что хотя введенный пароль был некорректен, но программа все равно была взломана через ошибку переполнения буфера. Для защиты от подобных случаев следует пользоваться функцией strncpy().

7

Расскажите про функцию free()

Следующая программа вылетает с ошибкой сегментации, если ввести freeze. Однако, если ввести zebra, то все будет хорошо. Почему? #include <stdio.h> int main(int argc, char *argv[]) { char *ptr = (char*)malloc(10); if(NULL == ptr) { printf("\n Malloc failed \n"); return -1; } else if(argc == 1) { printf("\n Usage \n"); } else { memset(ptr, 0, 10); strncpy(ptr, argv[1], 9); while(*ptr != 'z') { if(*ptr == '\0') break; else ptr++; } if(*ptr == 'z') { printf("\n String contains 'z'\n"); // Do some more processing } free(ptr); } return 0; } Здесь проблема заключается в том, что код изменяет адрес указателя ptr (путем инкремента переменной ptr) внутри цикла while. Когда пользователь вводит zebra, цикл while завершается без единой итерации, поэтому адрес, переданный функции free(), будет точно такой же, какой был присвоен функцией malloc(). Однако, в случае с freeze, значение переменной ptr изменяется внутри цикла while, что приводит к передаче неправильного адреса в функцию free() и ошибке сегментации.

Логотип ДевстанцииАвторизуйтесь, чтобы просматривать следующий контент
9

Расскажите про функции atexit() и _exit()

Логотип ДевстанцииАвторизуйтесь, чтобы получить доступ
10

Что не так со следующей функцией?

Логотип ДевстанцииАвторизуйтесь, чтобы получить доступ
11

Течёт ли тут память?

Логотип ДевстанцииАвторизуйтесь, чтобы получить доступ
12

void* и структуры C

Логотип ДевстанцииАвторизуйтесь, чтобы получить доступ
13

Операторы * и ++

Логотип ДевстанцииАвторизуйтесь, чтобы получить доступ
14

Реализуйте процесс, изменяющий свое имя

Логотип ДевстанцииАвторизуйтесь, чтобы получить доступ
15

Адрес локальной переменной

Логотип ДевстанцииАвторизуйтесь, чтобы получить доступ
16

В каких случаях используется ключевое слово static?

Логотип ДевстанцииАвторизуйтесь, чтобы получить доступ
17

Зачем используется volatile?

Логотип ДевстанцииАвторизуйтесь, чтобы получить доступ
18

Может ли указатель быть volatile?

Логотип ДевстанцииАвторизуйтесь, чтобы получить доступ
Хотите стать частью сообщества Девстанции?
Вступайте в наш чат в Telegram

Также в этой категории

Вопросник
  26 вопросов

Вопросы с собеседований по C++

Ответы на вопросы для собеседования C++ разработчика

978 просмотров
От 4 июня
Задачник
  32 задачи

Топ 35 задач с собеседований по C++

Разбор решений для алгоритмических задач с собеседований по C++

3087 просмотров
От 25 февраля

Вам может быть интересно

Викторина
  20 вопросов

Викторина по Django - Junior/Middle

Базовые вопросы с собеседования по Django

67 просмотров
От 2 июня 2023
Задачник
  90 задач

Топ 90 алгоритмических задач по Python

Подборка решений для задач с собеседований Python-разработчиков

17466 просмотров
От 27 июня
Викторина
  12 вопросов

Викторина по Python - Middle/Senior

Продвинутые вопросы для собеседования Python-разработчика

123 просмотра
От 30 мая 2023
Вопросник
  7 вопросов

Коллекция полезных команд для Docker

Большая шпаргалка по всем командам Docker

963 просмотра
От 12 октября 2023
Вопросник
  11 вопросов

Теория шардинга баз данных

О распределении данных между серверами

926 просмотров
От 10 октября 2023
Вопросник
  10 вопросов

Всё о репликации баз данных

Описание понятий и процессов репликации БД

1009 просмотров
От 8 октября 2023

Топ тредов

Gravatar for 1847arsen
Arsen
: Задача в Python под названием "Кратчайший путь в матрице"

Последнее сообщение:
Gravatar for 1847arsen
Arsen
: Ошибка на 3 тесте # Ожидаемый результат: 2 а должен быть 1
1 сообщение
31 просмотр

Gravatar for 1233freddypopa
freddypopa
: Добавить чекбокс, который отвечает за показ ранее тронутых задач (черновик)

Последнее сообщение:
: Отличная идея! Возьмём её на заметку!
1 сообщение
126 просмотров

: Предложите идею и получите спонсорский доступ на месяц

Последнее сообщение:
Gravatar for 1236borisops
Borisops
: Добавить темную тему) что бы можно было посмотреть сложность алгоритма и добавить тэги.
10 сообщений
341 просмотр

Все категории