2016-07-17 4 views
1

В настоящее время я изучаю работу динамического управления памятью, а более конкретно realloc и то, как это делается в функциях.C - realloc не отражает основную информацию

В следующей программе я просто хотел попытаться выделить некоторые числа в функции a(), используя malloc, а затем передать их другой функции b(). В b() я передаю адрес указателя на c(), чтобы перераспределить память в два раза по размеру и инициализировать ее цифрами.

Теперь подошел к моему вопросу: почему вывод в функции b() показывает правильные номера, но в основной функции это не так? Должна ли указатель «числа» в основном также указывать на перераспределенную память?

Заранее спасибо.

Код:

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

#define SIZE 3 

int a(int **numbers); 
int b(int *numbers); 
int c(int **numbers); 

int main() 
{ 
    int *numbers = NULL; 

    a(&numbers); 

    for(size_t i = 0; i < 2 * SIZE; i++) 
    printf("In main after a: %i\n", numbers[i]); 

    b(numbers); 

    for(size_t i = 0; i < 2 * SIZE; i++) 
    printf("In main after b: %i\n", numbers[i]); 

    return 0; 
} 

int a(int **numbers) 
{ 
    *numbers = malloc(SIZE * sizeof(numbers)); 
    if(!numbers) 
    { 
    free(numbers); 
    return -1; 
    } 


    for(size_t i = 0; i < SIZE; i++) 
    (*numbers)[i] = i; 

    return 0; 
} 

int b(int *numbers) 
{ 
    c(&numbers); 

    for(size_t i = 0; i < 2 * SIZE; i++) 
    printf("In b after c: %i\n", numbers[i]); 

    return 0; 
} 

int c(int **numbers) 
{ 
    int *n_new = realloc(*numbers, 2 * SIZE * sizeof(numbers)); 
    if(!n_new) 
    { 
    free(n_new); 
    return -1; 
    } 

    for(size_t i = 0; i < 2 * SIZE; i++) 
    n_new[i] = i * 2; 

    *numbers = n_new; 

    return 0; 
} 

Выход:

In main after a: 0 
In main after a: 1 
In main after a: 2 
In main after a: 0 
In main after a: 0 
In main after a: 0 
In b after c: 0 
In b after c: 2 
In b after c: 4 
In b after c: 6 
In b after c: 8 
In b after c: 10 
In main after b: 0 
In main after b: 0 
In main after b: 2 
In main after b: 0 
In main after b: 0 
In main after b: 0 
+0

Uh ... Сравните параметры 'a' и' b' и посмотрите, как они отличаются. Это различие заключается в том, почему 'a' может изменить значение указателя из' main', но 'b' не может. – hyde

+0

* Не следует ли указывать «номера» указателя в основном также на перераспределенную память? * Нет. Знаете ли вы, что такое «вызов по значению»? –

+0

Или ваш вопрос на самом деле, какая разница между 'int ** numbers' и' int * numbers'? – hyde

ответ

1

Вам нужно передать указатель на указатель на b(), а также. В его нынешнем виде вызов b(pointer) не может изменить указатель в main(). Сделайте это так же, как вы называете a(&pointer).

Кроме того, не надо звонить free() по указателям, которые, как вы знаете, являются нулевыми (когда malloc не удалось). Он ничего не делает.

+0

Спасибо за быстрый ответ! Означает ли это, что я должен добавить один указатель на каждую функцию, если я хочу перераспределить ее в более поздних функциях? Например, я хочу перераспределить указатель * p, который был объявлен в функции a(), в функции d(). Затем я передал (& p) -> b (& p) -> c (& p), а затем realloc в d? Тогда у меня будет 4-кратный указатель (**** p), объявленный в d? – sic

+0

@sic: Нет, вы всегда можете передать его как '& p'. Попробуй. –

+0

Еще раз спасибо за быстрый ответ, я попробую! – sic