Я посылаю int *** в функцию, и функция выполняет это задание, но когда я пытаюсь использовать указатель снаружи после функции, она равна NULL. Вот функция:
void pointerSort2(int* arr, unsigned int size, char ascend_flag, int*** pointers)
{
int i, j, *temp;
int** sort=new int*[size];
for (i=0;i<size;i++)
sort[i]=&arr[i];
if (ascend_flag==true)
{
for (i=0;i<size-1;i++)
{
for(j=0; j<size-1-i;j++)
{
if (*sort[j]>*sort[j+1])
{
temp=sort[j];
sort[j]=sort[j+1];
sort[j+1]=temp;
}
}
}
pointers=&sort;
}
Когда я пытаюсь использовать его после, указатель "0x000000 (???)"
int*** pointers
функции int*** pointers
- это локальная переменная функции. После выхода из этой переменной эта переменная будет уничтожена.
Я думаю, что вместо строки
pointers=&sort;
там должен быть
*pointers = sort;
pointers = &sort;
вызывает вашу проблему. sort
- указатель на указатель. Таким образом, это переменная, которая создается внутри локальной области действия функции.
Он исчезает, когда функция выходит.
Попробуйте удалить &
Мы хотим перейти к переменной локальных указателей, найти то, на что она указывает, и изменить это значение. указатели не передаются по ссылке, он, как и любой другой параметр, копируется и уничтожается за каждый вызов функции времени выполнения в стеке.
*pointers = sort;
Во-первых, если это не для назначения, контейнеры и алгоритмы уже существуют, что сделает все это для вас:
Контейнеры: std::vector
, std::list
, std::deque
Алгоритм сортировки: std::sort
Большинство ваших проблем уходят просто с помощью стандартных шаблонов библиотеки.
В остальном вы также, похоже, не хорошо понимаете разницу между передачей по значению и передачей по ссылке, а также семантикой указателя.
Передача int***
в функцию, которая принимает int***
Если вы объявите функцию как
void func(int i);
И назовите это:
int j = 0;
func(j);
Ничто, что func
не делает с параметром i
отражается в j
. Копия j
передается func
. Если вы хотите сохранить любые изменения func
сделанные в параметре i
, вам нужно либо использовать ссылку, либо указатель:
void func(int& i);
// or
void func(int* pI); // requires you to call it via func(&j)
То же самое касается вашего текущего кода:
Вы объявили свою функцию сортировки следующим образом
void pointerSort2(..., int*** pointers);
Если бы вы назвали это так
int*** myPointer = NULL;
pointerSort2(..., myPointer);
Вы передаете его по значению. Это скопирует значение указателя (в настоящее время NULL
) в pointers
локальной переменной функции. Когда функция возвращается, myPointer
не изменяется. Если ваша цель состоит в том, чтобы сохранить измененное значение в myPointer
, вам нужно либо пройти по ссылке, либо передать указатель на ваш int***
(ПРИМЕЧАНИЕ: этот уровень косвенности уже является запахом кода!) Потенциальные решения для этого было бы:
void pointerSort2(..., int***& pointers);
// or
void pointerSort2(..., int**** pointers);
Это позволит вам вызвать функцию этими способами (соответственно):
int*** myPointer = NULL;
pointerSort2(..., myPointer);
// or
pointerSort2(..., &myPointer);
Для первой версии вы должны установить значение pointers
на значение sort
вроде этого:
pointers = sort;
Поскольку pointers
являются ссылкой (псевдоним) на myPointer
, значение myPointer
изменяется.
Для второй версии вы должны установить значение pointers
на значение sort
вроде этого:
*pointers = sort;
Поскольку pointers
являются указателями на расположение myPointer
, вы устанавливаете фактическое значение myPointer
.
Обратите внимание, что в обоих случаях вы задаете значение для sort
(значение указателя), а не &sort
(адрес указателя).
Примечание
bool
- тип, который используется для значений true
и false
. Ваш параметр ascend_flag
будет лучше использоваться как bool
вместо char
.
new
.std::vector
?std::sort
? Рекомендации? Если бы вы использовали их, у вас не было бы таких проблем.