---
title: Память и указатели
seo:
  title: Память и указатели — C++ Developer
  description: Тема «Память и указатели» для собеседования C++ Developer. В чем разница между указателем и ссылкой? Для чего нужен указатель на функцию? Как его объявить?
---

[Все темы C++ Developer](/c-developer)

## <strong>В чем разница между указателем и ссылкой?</strong> [#q-14bee738d69b81c1bc98db4a99b620c7]

Основные различия между указателем и ссылкой в C++&#58;

{/* prettier-ignore */}
1. <strong>Синтаксис и использование</strong>&#58;

    - <strong>Указатель</strong>&#58; Переменная, которая хранит адрес другой переменной.

        ```cpp
        int a = 10;
        int* ptr = &a;
        ```

    - <strong>Ссылка</strong>&#58; Альтернативное имя для уже существующей переменной.

        ```cpp
        int a = 10;
        int& ref = a;
        ```

1. <strong>Инициализация</strong>&#58;

    - <strong>Указатель</strong>&#58; Может быть инициализирован позже или изменён для указания на другой адрес.

        ```cpp
        int b = 20;
        ptr = &b;  // Теперь ptr указывает на b
        ```

    - <strong>Ссылка</strong>&#58; Должна быть инициализирована сразу при создании и не может быть изменена для ссылок на другой объект.

        ```cpp
        int c = 20;
        ref = c;  // Изменяет значение a на 20, но ref по-прежнему ссылается на a
        ```

1. <strong>Нулевое значение</strong>&#58;

    - <strong>Указатель</strong>&#58; Может быть нулевым (<code>nullptr</code>), что означает, что он не указывает ни на какой объект.

        ```cpp
        int* ptr = nullptr;
        ```

    - Ссылку нужно связать с подходящим объектом или функцией. Сам язык не отслеживает время жизни цели&#58; после её уничтожения ссылка может стать висячей.

1. <strong>Операции разыменования</strong>&#58;

    - <strong>Указатель</strong>&#58; Требует операцию разыменования (<code>&#42;</code>) для доступа к значению, на которое указывает.

        ```cpp
        int value = *ptr;
        ```

    - <strong>Ссылка</strong>&#58; Не требует специальной операции для доступа к значению.

        ```cpp
        int value = ref;
        ```

Указатель можно переназначить и проверить на nullptr. Ссылка удобна как обязательный параметр и не переназначается, но не гарантирует время жизни объекта. В обоих случаях нужно избегать висячих обращений.

:::note[Ссылки для изучения]

1. [Ссылки. Указатели. Константность](https://education.yandex.ru/handbook/cpp/article/references-pointers-const)
   :::

---

## <strong>Для чего нужен указатель на функцию? Как его объявить?</strong> [#q-14bee738d69b81e6bbe3f7c6f01b4e1e]

Указатель на функцию используется для хранения адреса функции и позволяет вызывать функции через этот указатель. Это полезно для реализации обратных вызовов (callbacks), таблиц виртуальных функций и гибких механизмов обработки событий.

#### Объявление указателя на функцию&#58;

{/* prettier-ignore */}
1. <strong>Объявление</strong>&#58;

    - Для функции с прототипом <code>void foo&#40;int&#41;</code>&#58;

        ```cpp
        void (*funcPtr)(int);
        ```

1. <strong>Инициализация</strong>&#58;

    - Присвоение адреса функции указателю&#58;

        ```cpp
        funcPtr = foo;
        ```

1. <strong>Использование</strong>&#58;

    - Вызов функции через указатель&#58;

        ```cpp
        funcPtr(5);  // Вызывает foo(5)
        ```

Пример&#58;

```cpp
#include <iostream>// Обычная функция
void foo(int x) {
    std::cout << "Value: " << x << std::endl;
}

int main() {
    // Объявление указателя на функцию
    void (*funcPtr)(int);

    // Инициализация указателя адресом функции foo
    funcPtr = foo;

    // Вызов функции через указатель
    funcPtr(5);

    return 0;
}
```

:::note[Ссылки для изучения]

1. [Ссылки. Указатели. Константность](https://education.yandex.ru/handbook/cpp/article/references-pointers-const)
   :::

---

## <strong>Что будет, если забыть вызвать</strong> <code>delete</code><strong>? Когда освободится та память?</strong> [#q-14bee738d69b81058d8bca82b37832a2]

Если забыть вызвать <code>delete</code> для динамически выделенной памяти, произойдёт утечка памяти <code>&#40;memory leak&#41;</code>. В таком случае&#58;

- Память, выделенная с помощью <code>new</code>, не будет освобождена.

- Память будет занята до завершения программы.

- Постепенно такие утечки могут привести к исчерпанию доступной памяти, что может вызвать замедление или крах программы.

Память, не освобождённая через <code>delete</code>, будет освобождена операционной системой при завершении программы, но в процессе выполнения программы эта память останется недоступной для повторного использования.

:::note[Ссылки для изучения]

1. [Утечки памяти в C++](https://skillbox.ru/media/code/utechki_pamyati_v_c_chto_eto_takoe_i_chem_oni_opasny/)
   :::

---

## <strong>Что такое умный указатель? Какие умные указатели есть в стандартной библиотеке?</strong> [#q-14bee738d69b813880eee005470557e1]

Умный указатель хранит указатель и реализует правила владения. unique_ptr освобождает ресурс при уничтожении или reset, shared_ptr при исчезновении последнего владельца. weak_ptr не владеет объектом и сам его не освобождает.

1. <code>std&#58;&#58;unique&#95;ptr</code>&#58; Эксклюзивное владение ресурсом.
   Не может быть скопирован, только перемещён.

1. <code>std&#58;&#58;shared&#95;ptr</code>&#58; Совместное владение ресурсом.
   Поддерживает подсчёт ссылок, освобождает память, когда последний
   <code>shared&#95;ptr</code> выходит из области видимости.

1. <code>std&#58;&#58;weak&#95;ptr</code>&#58; Неблокирующая ссылка на ресурс,
   управляемый <code>std&#58;&#58;shared&#95;ptr</code>. Не увеличивает подсчёт
   ссылок.

Пример&#58;

```cpp
#include <memory>

std::unique_ptr<int> ptr1(new int(10));
std::shared_ptr<int> ptr2 = std::make_shared<int>(20);
std::weak_ptr<int> ptr3 = ptr2;
```

:::note[Ссылки для изучения]

1. [Ссылки. Указатели. Константность](https://education.yandex.ru/handbook/cpp/article/references-pointers-const)
   :::

---

## Как работает const для переменных, ссылок и указателей и от чего зависит размер указателя? [#q-14bee738d69b8165be4efb4c60b3dc73]

<strong>Константность переменной, ссылки, указателя&#58;</strong>

- <strong>Константная переменная</strong>&#58; Значение не может быть изменено
  после инициализации.

  ```cpp
  const int a = 10;
  ```

- <strong>Константная ссылка</strong>&#58; Ссылка на константу, через которую
  нельзя изменить значение.

  ```cpp
  const int& ref = a;
  ```

- <strong>Константный указатель</strong>&#58; Указатель, адрес которого нельзя
  изменить после инициализации.

  ```cpp
  int value = 10;
  int* const ptr = &value;
  ```

- <strong>Указатель на константу</strong>&#58; Указатель на значение, которое
  нельзя изменить через этот указатель.

  ```cpp
  const int* ptr = &a;
  ```

<strong>Константный указатель и указатель на константу&#58;</strong>

- <strong>Константный указатель (</strong>
  <code>int&#42; const</code>
  <strong>)</strong>&#58; Указатель не может указывать на другой адрес, но
  данные по этому адресу могут изменяться.

  ```cpp
  int value = 10;
  int* const ptr = &value;
  ```

- <strong>Указатель на константу (</strong>
  <code>const int&#42;</code>
  <strong>)</strong>&#58; Указатель может менять адрес, но данные по адресу
  менять нельзя.

  ```cpp
  const int* ptr = &a;
  ```

<strong>Размер указателя&#58;</strong>

- Размер указателя определяется типом указателя и реализацией; проверяйте sizeof. Следующие размеры типичны для распространённых ABI, но не гарантированы стандартом для всех платформ и указателей на члены.
  - <strong>32-битная система</strong>&#58; Указатель занимает 4 байта.

  - <strong>64-битная система</strong>&#58; Указатель занимает 8 байт.

:::note[Ссылки для изучения]

1. [Ссылки. Указатели. Константность](https://education.yandex.ru/handbook/cpp/article/references-pointers-const)
   :::

---

## <strong>Что случится, если вернуть ссылку на временный объект?</strong> [#q-14bee738d69b819a87f6ed9bbd2ac281]

Если вернуть ссылку на временный объект, то после завершения функции объект будет уничтожен, и ссылка станет <strong>"висячей"</strong> <code>&#40;dangling reference&#41;</code>. Использование такой ссылки приведёт к неопределённому поведению, что может вызвать ошибки или сбои программы.

:::note[Ссылки для изучения]

1. [Ссылки. Указатели. Константность](https://education.yandex.ru/handbook/cpp/article/references-pointers-const)
   :::
