выделение памяти (пере) внутри функции по указателю - PullRequest
0 голосов
/ 24 января 2011

например:

void f(void *p) {
    p = malloc(1);
    printf("%i\n", p);
}

void main(int argc, char *argv[]) {
    void *p = malloc(1);
    printf("%i\n", p);
    f(p);
    printf("%i\n", p);
}

будет производить что-то вроде этого:

5513696
5513728
5513696

Почему передача по адресу и распределение не изменит адрес указателя?ps где может быть что-то вроде realloc (может быть, даже рекурсивный realloc при вызове функции recusrive)

Ответы [ 7 ]

3 голосов
/ 24 января 2011

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

2 голосов
/ 24 января 2011

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

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

Если вы хотите изменить указатель , вам нужно передать еще один указатель на it , например:

#include <stdio.h>
#include <stdlib.h>

void f (void **p){
    // free (*p);         // add in to avoid memory leak
    *p = malloc (1);
    printf ("%i\n", *p);
}

int main (int argc, char *argv[]){
    void *p = malloc (1);
    printf ("%i\n", p);
    f (&p);
    printf ("%i\n", p);
    return 0;
}

Это выводит:

6750728
6816336
6816336

как и ожидалось на моей машине.

1 голос
/ 24 января 2011

Вы должны сделать:

void f(void **p){
  *p=malloc(1);
  printf("%i\n",*p);
}

void main(int argc,char *argv[]){
  void *p=malloc(1);
  printf("%i\n",p);
  f(&p);
  printf("%i\n",p);
}
1 голос
/ 24 января 2011

Когда вы вызываете p, он получает копию указателя («передача по значению»), которая сбрасывается при возврате функции. Вместо этого вы можете передать адрес указателя.

void f(void** p){
  *p= ... whatever you want
}
0 голосов
/ 24 января 2011

Это связано с тем, как вызовы функций C и стек работают. Боюсь, это может показаться немного сложным, когда написано.

Сначала указатель p-of-main размещается в стеке. Затем готовится вызов функции. Для этого все целые значения должны быть скопированы в стек, поэтому копируется значение p-of-main и выполняется функция f. Теперь f может видеть только скопированное значение в пространстве аргументов, но это не та же область памяти, что и p-of-main, это фактически новая «переменная»: p-of-f.

Чтобы достичь того, что вы хотите сделать, вам действительно нужно передать указатель на указатель (я пометил измененные строки с помощью // !):

void f(void **p){     // !
  *p=malloc(1);       // !
  printf("%i\n",*p);  // !
}

void main(int argc,char *argv[]){
  void *p=malloc(1);  // !
  printf("%i\n",p);
  f(&p);              // !
  printf("%i\n",p);
}
0 голосов
/ 24 января 2011

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

void f(void *& p)
0 голосов
/ 24 января 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...