Простой c malloc - PullRequest
       1

Простой c malloc

1 голос
/ 20 мая 2010

это не работает:

void function(char* var)
{
    var = (char*) malloc (100);
}

int main()
{
    char* str;
    function(str);
    strcpy(str, "some random string");
    printf("%s\n", str);

    return 0;
}

это делает:

void function(char* var)
{
    //var = (char*) malloc (100);
}

int main()
{
    char* str;
    //function(str);
    str = (char*) malloc (100);
    strcpy(str, "some random string");
    printf("%s\n", str);

    return 0;
}

Почему?

Ответы [ 5 ]

13 голосов
/ 20 мая 2010

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

void function(char** var)
{
    *var = malloc (100);
}

int main()
{
    char* str;
    function(&str);
    strcpy(str, "some random string");
    printf("%s\n", str);

    return 0;
}
4 голосов
/ 20 мая 2010

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

Вам необходимо получить char ** и сделать:

my_alloc_fun(void **ptr){
    *ptr= malloc(size);
}
void *myptr;
my_alloc_fun(&myptr);

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

3 голосов
/ 20 мая 2010

Когда вы звоните function(str), вы передаете значение от str до function. Это значение является неинициализированным значением мусора, потому что вы не установили его в main, но это не проблема.

Проблема в том, что function имеет свой собственный указатель, var, в который он помещает это значение мусора, чтобы можно было сказать var points to the same thing (garbage) that str points to. Однако они не являются одной и той же переменной. Это две разные переменные, и изменение var не влияет на str.

Когда вы говорите var = (char*) malloc (100);, вы выделяете память где-то, а затем говорите var, чтобы указать на нее. Теперь var указывает на местоположение, отличное от str. Вы сразу же возвращаетесь из этой функции, теряя var и расположение этой памяти. Это, кстати, утечка памяти.

Когда вы вернетесь к main, str будет таким, каким он был когда-то, - указывая на мусор.

Числовой пример:

char *str;     // str -> 0xfeedface   (garbage)
function(str);

// inside 'function', an initialization like this occurs
char *var = str;  // var -> 0xfeedface (same garbage)
var = (char*) malloc (100); // var -> 0x12341234 (alloc'd memory)
return;

// back in 'main'
strcpy(str, "some random string"); // str still points to 0xfeedface!

Чтобы сделать это правильно, вам нужно изменить значение str s. Это означает, что function нужен указатель на str или указатель на указатель .

void function(char **var)
{
   *var = (char*)malloc(sizeof(char) * 100);
}

int main()
{
   char *str;
   function(&str);
   strncpy(str, "some random string", 99);
   ...
   free(str);  // important in general
}
1 голос
/ 21 мая 2010

Указатели, как и любая другая переменная; разница только в том, что представляет их ценность. В то время как double имеет значение, представляющее число с плавающей запятой двойной точности, а int имеет значение, представляющее целое число со знаком, указатель имеет значение, представляющее местоположение другой переменной.

Сами указатели все еще передаются по значению другим функциям; поэтому ваш пример не работает по той же причине, по которой не работает эта анагональная функция:

void function(int var)
{
    var = 100;
}

int main()
{
    int num;
    function(num);
    printf("%d\n", num);

    return 0;
}

Ответ в обоих случаях один и тот же: когда function() изменяет значение параметра var, он меняет только свою локальную копию - он не меняет переменную в пределах main().

0 голосов
/ 20 мая 2010

См. Мой ответ на C Программирование: malloc () внутри другой функции для объяснения того, как об этом думать.

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