Почему я получаю разные значения, если я обращаюсь к глобально объявленным элементам массива, используя пользовательскую функцию и функцию main ()? - PullRequest
0 голосов
/ 05 октября 2019

Я написал этот код C, в котором int* arrayInit(); присваивает значения глобально объявленному массиву из 3 элементов и возвращает адрес первого элемента массива. В Сегменте 1 элементы массива и их соответствующие адресапечатается с использованием функции fuction int* arrayInit(), а те же элементы и адреса печатаются в сегменте 2 с использованием функции void main(). Вот код:

#include<stdio.h>

int array[3];   //global declaration of array

int *arrayInit()
   {
    int array[]={1,2,3};
    int* ptr=&array[0];

    /*Segment 1:
      To print the array elements and its address using
      user-defined function*/
    printf("\nSegment 1 : Through User-Defined Function:");
    for(int i=0;i<3;i++)
        printf("\n%d\t%p",array[i],&array[i]);

    return ptr;
   }

void main()
   {
    int *pointer=arrayInit();        //storing address returned by arrayInit()

    /*Segment 2:
      To print the array elements and its address using
      user-defined function*/ 
    printf("\n\nSegment 2 : Through Main Function:");
    for(int i=0;i<3;i++)     //will perform the operation 3 times
         {
          printf("\n%d\t%p",*pointer,pointer);
          pointer++;
         }
   }

Когда я запускаю этот код, я получаю результат, примерно такой:

Segment 1 : Through User-Defined Function:
1       0061FEDC
2       0061FEE0
3       0061FEE4

Segment 2 : Through Main Function:
24      0061FEDC
6422220 0061FEE0
3       0061FEE4

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

Спасибо.

Ответы [ 2 ]

3 голосов
/ 05 октября 2019

Ваша arrayInit функция вообще не имеет доступа к глобальному array. Он имеет свой собственный локальный array, который скрывает глобальный.

Затем он возвращает указатель на этот массив local - поэтому main получает указатель на этот локальный. Но этот массив перестает существовать, как только возвращается функция arrayInit. Таким образом, чтение из этого указателя в main является неопределенным поведением.

Либо:

  • инициализирует массив в глобальной области видимости (и вообще не использует функцию arrayInit)
  • инициализируйте массив в initArray: там нет локального с таким же именем, просто заполните глобальное
  • , динамически выделите массив в initArraymalloc). В этом случае main становится ответственным за free его.

Пример для второго пункта:

#include <stdio.h>

int array[3];

void arrayInit() {
  for (int i=0; i<3; i++) {
    array[i] = i+1;
  }
}

int main() {
  arrayInit();

  for (int i=0; i<3; i++) {
    printf("%d\t%p\n", array[i], &array[i]);
  }
}
0 голосов
/ 05 октября 2019
int array[]={1,2,3};

Все проблемы заключаются в этом утверждении. На самом деле, Array, который вы объявили в глобальном пространстве, вообще не доступен. Поскольку вы снова объявили array в локальном пространстве функции arrayInit, у нее есть собственный массив. Либо добавьте внешнюю декларацию, либо malloc.

В некоторых компиляциях, таких как мой (GCC 6.3), вы можете получить желаемый результат, потому что программа короткая, а переменная не имеет доступа к выделенному Initialized Data Segment. Но существует опасность того, что эти данные будут перезаписаны, поскольку, как только возвращается значение из arrayInit, память, связанная с локальным array, освобождается и становится доступной для других переменных.

Правильная версия:

#include<stdio.h>

int array[3];   //global declaration of array

int *arrayInit()
   {
    extern int array[3];
    array[0]=1;
    array[1]=2;
    array[2]=3;
    int* ptr=&array[0];

    printf("\nSegment 1 : Through User-Defined Function:");
    for(int i=0;i<3;i++)
        printf("\n%d\t%p",array[i],&array[i]);

    return ptr;
   }

void main()
   {
    int *pointer=arrayInit();        

    printf("\n\nSegment 2 : Through Main Function:");
    for(int i=0;i<3;i++)     //will perform the operation 3 times
         {
          printf("\n%d\t%p",*pointer,pointer);
          pointer++;
         }
   }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...