Невозможно выделить память с помощью new [] из шаблонной функции - PullRequest
0 голосов
/ 16 июня 2020

Я пытаюсь создать функцию, которая выделяет память. Он выделяет его, но проблема в том, что он делает это только внутри функции, но после возврата выделенной памяти больше нет. Как будто я выделяю память другим указателем, но другого там быть не должно.

template<class T> struct rmv_ptr { using type = T; };
template<class T> struct rmv_ptr<T*> { using type = T; };
template<class T> struct rmv_ptr<const T*> { using type = T; };

template<class T> bool alloc(T inst, int size)
{
    return (nullptr != (inst = new typename rmv_ptr<T>::type[size]));
}

Скажем, я называю это так: 1008 *, поэтому указатель a должен указывать на выделенную память, нет?

Ответы [ 2 ]

1 голос
/ 16 июня 2020

Указатели ничем не отличаются от указателей, поскольку модификации не видны снаружи при передаче по значению функции:

void foo(int* p) { p = 0; }    // only modifies the local p
void foo(int  a) { a = 0; }    // only modifies the local a

Однако указатели позволяют вам изменять то, на что указывает указатель, и что может наблюдаться вызывающим абонентом:

// assume p points to an int
void bar(int* p) { *p = 42; }

Это не изменит сам p. При вызове через

int x;
int xp = &x;
bar(xp);

тогда p внутри bar является копией xp, хотя оба они указывают на один и тот же int.

Но когда вы звоните new, затем new вернет вам указатель на выделенную память, поэтому вам нужно изменить значение указателей, а не только указатель. Либо передайте его по ссылке, либо верните указатель из функции (делая его параметром в любом случае бесполезно).

1 голос
/ 16 июня 2020

Когда вы передаете целое число в функцию, вы не можете его изменить.

Когда вы передаете указатель на функцию, вы не можете изменить указатель.

Когда вы передаете указатель для функции вы можете изменить указанное значение.

Передача по неконстантной ссылке является исключением; это позволяет вам изменить переданное значение. Таким образом, передача указателя по ссылке позволяет изменить указатель.


С другой стороны, базовое правило для logi c шаблона «удалить указатель» не будет работать. Проблема в том, что у вас есть два использования T. Есть аргумент T& inst, который должен соответствовать T*, возвращаемому new. Т.е. если T равно int, то rmv_ptr<int>::type равно int, а new вернет int*. Но вы не можете назначить это int* на int& inst.

...