Это проходит по указателю? - PullRequest
3 голосов
/ 08 декабря 2011
void func(char* buf) { buf++;}

Должен ли я назвать это передачей по указателю или просто передачей по значению (со значением, являющимся типом указателя)? Будет ли в этом случае изменен исходный указатель?

Ответы [ 4 ]

5 голосов
/ 08 декабря 2011

Это передается по значению.

void func( char * b )
{
    b = new char[4];
}

int main()
{
    char* buf = 0;
    func( buf );
    delete buf;
    return 0;
}

buf все равно будет 0 после вызова func и утечка новой памяти.

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

Правильный способ выполнения вышеуказанных действий будет

ALTERNATIVE 1

void func( char *& b )
{
    b = new char[4];
}

int main()
{
    char* buf = 0;
    func( buf );
    delete buf;
    return 0;
}

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

ALTERNATIVE 2

Другой альтернативой является передача указателя на указатель, например

void func( char ** b )
{
    *b = new char[4];
}

int main()
{
    char* buf = 0;
    func( &buf );
    delete buf;
    return 0;
}

Обратите внимание, что я никоим образом не защищаюиспользование обнаженных указателей и ручное управление памятью, как показано выше, но просто для иллюстрации проходящего указателя.C ++ может использовать вместо std::string или std::vector<char>.

0 голосов
/ 08 декабря 2011

Чтобы реализовать ссылочную семантику через «передачу указателя», должны произойти две вещи: вызывающий должен взять «адрес» передаваемой вещи, и вызываемый должен разыменовать указатель.

Partsэто может быть скрыто использованием массивов, которые уменьшаются до указателя на первый элемент - в этом смысле содержимое массива всегда «передается по ссылке».Вы можете использовать «массив одного», чтобы скрыть разыменование.

Это прямой подход:

void increment_me(int * n) { ++*n; }    // note the dereference

int main() { int n; increment_me(&n); } // note the address-of

Вот то же самое в маскировке:

void increment_me(int n[]) { ++n[0]; }     // no visible *  
int main() { int n[1]; increment_me(n); }  // or &
0 голосов
/ 08 декабря 2011

Сам указатель передается по значению (указанная память передается указателем). Изменение параметра внутри функции не повлияет на указатель, который был передан.

0 голосов
/ 08 декабря 2011

Указатель не будет изменен.Передача указателем означает передачу адреса.Если вы хотите, чтобы указатель был изменен, вы должны передать двойной указатель один раз.

...