返回指向数组的指针

时间:2018-11-13 16:36:51

标签: c arrays function pointers

我编写了一个函数,该函数创建一个数据表,将其元素初始化为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 :(得分:2)

函数终止时,其所有自动变量将超出范围

tab在这种情况下是一个自动变量,并且在函数终止时将超出范围。现在,您将指针返回到本地数组,因此当数组超出范围时,您会发现自己带有 dangling pointer

您的编译器是否就此警告过您?在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()时,建议您阅读以下内容:Should I check if malloc() was successful?

答案 1 :(得分:2)

永远不要返回指向本地对象的指针。函数完成后,将释放该本地对象,并留下一个悬空的指针(该指针未指向有效内存)。

一种方法是在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;
}

答案 2 :(得分:1)

这里:

// 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)),否则它将保留到程序结束(可能会发生memory leak)。