Глобальные указатели между функциями - PullRequest
0 голосов
/ 07 июня 2019

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

Вот мой файл fun.c

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

int *step;
int step_counter;

int init(int num){
    step = &num;
    step_counter = *step;
    return 0;

}
void reset_counter(){
    step_counter = *step;
    printf("%d ", step_counter);

}

Вот файл main.c

#include <stdio.h>
#include <stdlib.h>
#include "fun.c"

int main()
{
    init(3);
    reset_counter();
return 0;
}

Я ожидал, что функция reset_counter выведет 3. Новместо этого он печатает 0. Я не знаю, в чем проблема.Я довольно новичок в C.

Ответы [ 2 ]

3 голосов
/ 07 июня 2019

У вас неопределенное поведение.

Вы указываете step на адрес num, но num - это локальная переменная, которая уничтожается после возврата init(). Попытка разыменовать step в reset_counter() дает вам UB, поскольку то, на что он указывает, уже уничтожено.

Почему вы используете указатель для step? Вы можете просто использовать step = num; и step быть int.

1 голос
/ 07 июня 2019

В этой функции

int init(int num){
    step = &num;
    step_counter = *step;
    return 0;

}

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

В результате указатель step будет иметь недопустимое значение, и программа будет иметь неопределенное поведение, еслион попытается получить доступ к памяти, на которую указывает указатель.

Вы можете переписать функцию следующим образом.

int init(int num){
    step = malloc( sizeof( *step );

    int success step != NULL;

    if ( success )
    {
        *step = num;
        step_counter = *step;
    }

    return success;
}

Не забудьте забыть освободить указатель перед выходом из программы..

Хотя неясно, зачем вам нужна дополнительная переменная step_counter.

Я бы переписал фрагмент кода следующим образом

int *step;

int init(int num){
    step = malloc( sizeof( *step ) );

    int success = step != NULL;

    if ( success ) *step = num;

    return success;
}

void reset_step(){
    free( step );
    step = NULL;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...