Возврат указателя на массив - PullRequest
0 голосов
/ 13 ноября 2018

Я написал функцию, которая создает таблицу данных, инициализирует ее элементы 0 и возвращает указатель на таблицу данных. Однако это не работает. Может ли кто-нибудь объяснить мне, чтобы я понял, где моя проблема. Это мой код:

#include <stdio.h>

// Here I create the data table and initialize it's elements
int* tabinit(int size) {
  int tab[size];

  for (int i = 0; i < size; i++)
    tab[i] = 0;
  return tab;
}

int main() {
  int* t = tabinit(10);

  for (int i = 0; i < 10; i++)
    printf("%d ", t[i]);
  printf("\n");
  return 0;
}

Ответы [ 3 ]

0 голосов
/ 13 ноября 2018

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

Один из способов сделать это - создать ваш объект в mainи передайте его в свою функцию для init, например, так:

void tabinit(int* tab, int size) {
  for (int i = 0; i < size; i++)
    tab[i] = 0;
}

int main() {
  int t[10];
  tabinit(t, 10);

  for (int i = 0; i < 10; i++)
    printf("%d ", t[i]);
  printf("\n");
  return 0;
}
0 голосов
/ 13 ноября 2018

Здесь:

// Here I create the data table and initialize it's elements
int* tabinit(int size) {
  int tab[size]; // <------- here

  for (int i = 0; i < size; i++)
    tab[i] = 0;
  return tab;    // <------- also here
}

Как сказал gsamaras, содержимое, на которое указывает tab, выходит из области видимости после вызова функции. Вы можете изменить эту строку:

int tab[size];

Автор:

int *tab;
tab = malloc(size * sizeof(int));

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

0 голосов
/ 13 ноября 2018

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

tab - это автоматическая переменная в этом случае, и она выйдет из области видимости после завершения функции.Теперь вы возвращаете указатель в локальный массив , поэтому, когда массив выходит из области видимости, вы окажетесь с висящим указателем .

Разве ваш компилятор не предупреждал вас об этом?В GCC я получил это предупреждение:

warning: function returns address of local variable [-Wreturn-local-addr]
   return tab;
          ^~~

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

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

Пример:

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


int* tabinit(int size) {
  int *tab = malloc(size * sizeof(int));

  for (int i = 0; i < size; i++)
    tab[i] = 0;
  return tab;
}

int main() {
  int* t = tabinit(10);

  for (int i = 0; i < 10; i++)
    printf("%d ", t[i]);
  printf("\n");

  // do NOT forget to free
  free(t);

  return 0;
}

Вывод:

0 0 0 0 0 0 0 0 0 0

PS: Когда вы познакомитесь с malloc(), я предлагаю вам прочитать это: Должен ли я проверить, если malloc ()был успешным?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...