@sabn1k
Возможно я написал чепуху, но попытайтесь понять

Указатель на указатель?

Насколько часто и где применяют указатели на указатели? И нужно ли это вообще?
  • Вопрос задан
  • 3502 просмотра
Пригласить эксперта
Ответы на вопрос 5
@MiiNiPaa
В современном С++ вообще указателей стараются избегать. Но вот несколько примеров:

Псевдо2D массив — массив массивов

Массив указателей. Например вектор хранит внутри указатель на буфер. .data() возвращает этот указатель. Если там хранятся указатели, получается указатель на указатель.

Когда нужно изменить указатель и используется АПИ С: указатель на объект используется если нужно изменить объект так, чтобы ето было видно вне изменяющей функции. В данном случае объект — другой указатель.
Ответ написан
@abcd0x00
Вот в этой строке argv - это указатель на указатель на строку.
int main(int argc, char *argv[])
Аргументы программы представлены в виде массива указателей на строки, в котором последний указатель равен нулю (нулевому указателю).

Бывает, что эту строку записывают и так
int main(int argc, char **argv)
Ошибки нет. Просто пишут скобки, чтобы напомнить, что там массив указателей, а не просто один указатель какой-то.

И дальше что? Правильно, ты можешь делать argv++, переходя по массиву указателей вправо.

А как сделать функцию, которая сама бы переставила argv?
void func(char ***p) { (*p)++; }
...
    func(&argv);

Пример
#include <iostream>

using namespace std;

void func(char ***p)
{
    (*p)++;
}

int main(int argc, char *argv[])
{
    cout << argv << " " << *argv << endl;
    func(&argv);
    cout << argv << " " << ((*argv) ? *argv : "no") << endl;
    return 0;
}

Вывод
[guest@localhost cpp]$ .iso++ t.cpp -o t
[guest@localhost cpp]$ ./t
0xbffc3114 ./t
0xbffc3118 no
[guest@localhost cpp]$ ./t a
0xbf999594 ./t
0xbf999598 a
[guest@localhost cpp]$

Ответ написан
Комментировать
@alex-t
Прогр. в команде rco.ru
Указатель на указатель часто встречается в "старых" интерфейсах С++ и в "просто С", когда надо в функции выделить память и что-то туда положить. Что-то типа
int foo(int **bar)
{
	*bar = new int;
	**bar = 123;
	return 0; // код ошибки
}

В современном С++ лучше написать функцию вида
std::unique_ptr<int> foo();
а возможные ошибки реализовать на исключениях, так и память не утечет, и код ошибки при каждом вызове проверять не надо. Кроме того, возврат автоуказателя не вызовет у "вызывающего" кода вопросов, должен ли он потом освободить память полученную по указателю, или нет.
Ответ написан
Комментировать
@asd111
Обычно делают вложенные структуры или вложенные классы.
Т.е. делаем структуру в которой лежит указатель, потом на эту структуру делаем указатель и т.д.
Указатель на указатель редко используют.
Сейчас вместо обычных указателей в С++ принято использовать умные указатели.
std::unique_ptr
std::shared_ptr
std::weak_ptr
Ответ написан
Комментировать
@maxwolf
С теоретической точки зрения, "указатель на указатель" - это просто отражение иерархии представления данных. Т.е. по мере увеличения сложности взаимных отношений в обрабатываемых данных может потребоваться и указатель на указатель на указатель и т.д. Простейший пример - путь в графе. Список (сам по себе строится на указателях) указателей на вершины графа (которые тоже суть указатели на другие вершины). С практической точки зрения, нужно чётко представлять себе все преимущества и недостатки каждого способа работы с указателями (так, например, shared_ptr это не какая-то абстрактная "магия", а специальный объект, который добавляет удобства, но берёт за это плату в виде дополнительной памяти и дополнительных действий, скрытых в примитивных операциях).
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы