2016-10-24 4 views
-3

Я хотел бы помочь понять этот код:Указывая локальную переменную

void F (int a, int *b) 
{ 
    a = 7 ; 
    *b = a ; 
    *b = 4 ; 
    printf("%d, %d\n", a, *b); 
    b = &a ; 
} 


int main() 
{ 
    int m = 3, n = 5; 
    F(m, &n) ; 
    printf("%d, %d\n", m, n) ; 
    return 0; 
} 

Я смущен, почему это не приводит к неожиданному поведению. В конце функции F значение b равно 7. Но когда я возвращаюсь, становится ясно, что после «b = & a» влияет значение n/b. Я думал, что указание на локальную переменную приведет к мусору/неожиданному поведению при изменении области действия, но это, похоже, не так.

+1

* Я смущен, почему это не приводит к неожиданному поведению * - так что вы ожидаете * неожиданного поведения? Гектометр Здесь я вижу противоречие ... –

+0

в конце функции 'F',' b' равно адресу 'a', а' a' является локальным для функции 'F'. – yano

+2

Итак, какое поведение ** ** вы ожидали неожиданности? Ну, это приводит к _un ** определенному ** behaviour_. Разве этого недостаточно? Как насчет чтения man-страниц функций, которые вы используете? '% d' принимает аргумент' int', а не указатель! – Olaf

ответ

2

Когда вы вызываете F, вы передаете значение m и адрес n. В F, b является указателем на n, так что при изменении значения * b изменяется значение n. Однако в "b = & a;" вы меняете, где b указывает. После этой строки b больше не указывает на n. Вместо этого он указывает на a. Эта строка ничего не делает для переменной n в main(). После этого, если вы измените значение * b, вы измените значение * b и его псевдоним, a. Он не изменит значение n в main.

+0

Спасибо за быстрый ответ. Я был под (ошибочным) предположением, что параметр int * b был синонимом n. – JohnKraz

+0

* b "был" синонимом n. Строка «b = & a» изменяет значение * b. После этого * b является синонимом a. – tjhighley

+0

Да, я думаю, я забыл, что я проходил мимо. По какой-то причине я думал, что n также является указателем на int. – JohnKraz

0

В конце функции F, значение b является 7

Значение b не 7; b устанавливается, чтобы указать на a, который имеет значение 7

Но когда я вернусь, то очевидно, что ничего после b = &a влияет на значение из n

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

В самом деле, вы не можете вызвать неопределенное поведение в main действиями внутри F, потому что main не получает каких-либо указателей от F. Если вы хотите сделать неопределенное поведение, передать указатель на указатель на F, и назначить его, чтобы указать на локальную переменную:

void CauseUB(int a, int **b) { 
    *b = &a; 
} 
int main() { 
    int x = 5, *y = &x; 
    printf("This is OK: %d\n", *y); 
    CauseUB(x, &y); // Pointer to pointer 
    printf("This is UB: %d\n", *y); 
    return 0; 
} 

Demo.

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