2013-11-21 3 views
0
int** array = (int**) malloc(1*sizeof(int*)); 
int* int_in_array = (int*) malloc(1*sizeof(int)); 
*int_in_array = 6 
array[0] = int_in_array; 

и пусть яРазыменование освободил указатель в C

free(array) 

Могу ли я рассчитывать на то, что *int_in_array даст мне 6?

Теперь предположим, кроме того, я

free(array[0]) 

тогда, могу ли я рассчитывать на то, что *int_in_array даст мне 6, так как int_in_array все еще указывает на 6?

большое спасибо!

+3

[Пожалуйста, не набрасывайте возвращаемое значение 'malloc()' in C] (http://stackoverflow.com/a/605858/28169). – unwind

+0

@unwind Вы должны указать возвращаемое значение 'malloc()', потому что оно возвращает 'void *', правильно? –

ответ

0
int** array = (int**) malloc(1*sizeof(int*)); 
int* int_in_array = (int*) malloc(1*sizeof(int)); 
*int_in_array = 6 
array[0] = int_in_array; 

после выполнения free(array) вы все еще можете получить доступ и использовать int_in_array. Но вы не можете позвонить free(array[0]), потому что вы не можете использовать array.

Если вы не звоните free(array), но только free(array[0]), вы не можете использовать *int_in_array, потому что вы освободили память.

2

Кажется, что у вас есть ментальная модель, где вы ожидаете, что указатели будут контролироваться магическим образом, так что один указатель «знает», что происходит с другим.

Это не то, как указатели, или модель памяти C, работают вообще.

Нет связи между различными указателями. Если два указателя указывают на один и тот же адрес, а один из них free(), другой становится недействительным , но его значение не изменяется. Также значение первого; это просто, что разыменование одного из них просто стало недействительным.

Рассмотрим это:

int *a = malloc(sizeof *a); 

if(a != NULL) 
{ 
    int *b = a; 
    *a = 4711; 

    printf("a=%p\nb=%p\n", (void *) a, (void *) b); 
    free(b); /* same pointer that malloc() returned, this is fine */ 
    printf("a=%p\nb=%p\n", (void *) a, (void *) b); 
} 

выше будет печатать на тот же адрес в четыре раза, так как значение любого из указателей не меняется только потому, что вы называете free() на одном из них. Помните, что free() не волшебство, это просто функция. С ним нет специальных скрытых функций, вы можете написать свои собственные malloc() и free(), если вам это нравится, и получите ту же семантику.

0
  1. 6 хранится в памяти, на которую указывает int * int_in_array.

    Так что если вы free() этой памяти (делая free(int_in_array)), 6 ушел или, по крайней мере, не был доступен больше, не вызывая неопределенного поведения.

  2. В памяти, на которую указывает array, хранится копия значения int_in_array. Таким образом, free() Эта копия по вызову free(array) не влияет на то, что хранится в int_in_array. И никоим образом не влияет на это значение, на которое указывает это значение.

    Доступ к данным, на которые указывает массив, можно получить либо с помощью *array, либо путем выполнения array[0].Поскольку он хранит копию int_in_array, делает free(array[0] так же, как и free(int_in_array). с теми же результатами о доступе 6, как упоминалось в 1.

0

Когда вы звоните free(array), int_in_array по-прежнему гарантированно указать на куске памяти, содержащей 6. array может продолжать или не продолжать указывать на int_in_array в зависимости от того, нужна ли память, которую он использовал для заселения, где-то в другом месте или целый ряд других обстоятельств.

Когда вы вызываете free(int_in_array), вы сообщаете системе, что вам больше не нужна память, содержащая 6. Значение указателя будет по-прежнему одинаковым, но вам больше не гарантируется, что 6 по-прежнему будет значением, хранящимся в этом месте.

Смежные вопросы