644 просмотра
От 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++ разработчика

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

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

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

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

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

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

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

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

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

Топ 60 вопросов про базы данных и SQL

Ответы на вопросы с собеседований по БД и SQL

1198 просмотров
От 4 июня
Викторина
  20 вопросов

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

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

51 просмотр
От 2 июня 2023
Вопросник
  10 вопросов

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

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

743 просмотра
От 8 октября 2023
Вопросник
  7 вопросов

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

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

741 просмотр
От 12 октября 2023
Задачник
  90 задач

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

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

12279 просмотров
От 27 июня

Топ тредов

Gravatar for 815unicozz
unicozz
: Задача в JS под названием "Соревнование" содержит ошибку

Последнее сообщение:
: Привет! В примерах вызова функции действительно была опечатка, исправили. Однако, должен получиться...
2 сообщения
64 просмотра

: Добавьте возможность ставить реакции на решенные задачи других коллег)

Последнее сообщение:
: Это здорово, я думаю наше сообщество будет приятно удивлено такому нововведению, успешного перевопло...
2 сообщения
91 просмотр

Gravatar for 999jackflagg
jackflagg
: Добавьте разделы по MongoDB и Nest.js

Последнее сообщение:
: Принято! Разместим контент по этим технологиям в категории Node.js. Но нужно немного подождать, сейч...
1 сообщение
49 просмотров

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