【问题标题】:Passing and returning arrays in C [duplicate]在C中传递和返回数组[重复]
【发布时间】:2014-10-28 19:02:07
【问题描述】:

以下是两个代码sn-ps。一个工作正常,但另一个失败。

主要功能

int main
{
  int *x,*y,n,*c;
  //some code
  c=myfunc(x,y,n);
  //rest code
}

这是有效的代码:

int * myfunc(int *a, int *b, int n)
{
  int *s,i,*t;
  for(i=0;i<n;i++)
      s[i]=x[i]+y[i];
  t=s;
  return s;
}

这是不起作用的代码

int * myfunc(int *a, int *b, int n)
{
  int s[100],i,*t;
  for(i=0;i<n;i++)
      s[i]=x[i]+y[i];
  t=&s[0];
  return t;
}

这里发生的情况是,即使返回的值是正确的地址(经过测试和检查),内容似乎也会自行修改。然而,在第一种情况下似乎并非如此。

不仅如此,s[100] 的整个数组在执行查询的末尾也有不同的内容。这基本上意味着所有这些地址的内容都由于某种随机原因而被修改。

使用的编译器是 Turbo C。


编辑

直截了当的问题:

为什么初始化为s[100]时s的内容在返回后会被重置,而初始化为*s时s的内容不会重置。请注意:我没有使用 malloc() 或与我的代码中任何位置的堆栈有关的函数。

【问题讨论】:

  • 这个问题并没有完全达到我的查询重点。我的疑问是,为什么 *s 初始化工作而不是 s[100]。我的其余代码很简单。没有使用 malloc() 函数,没有复杂化。
  • 查看我的其他评论。在这两种情况下,就我们所见(除了 int *s 的隐藏的、绝密的初始化之外),您有未定义的行为。没有理由期望任何一个版本都能做任何特别的事情。移动一些代码,重新排序一些函数调用,其他版本现在可能出现可以工作。出于任何充分的理由,两者都不应该起作用。
  • 对不起,最高机密的初始化大声笑...我认为这只是一段垃圾代码,因为它没有做任何特别的事情。在问题中添加了整个功能。谢谢

标签: c arrays function pointers


【解决方案1】:

没有什么随机的。您正在返回一个局部变量的地址,一旦函数返回,该地址就不再存在。为将来的函数调用、变量等释放空间。

int * myfunc(int *a, int *b, int n)
{
   int s[100],i,*t;
   //some operation
   t=&s[0];
   return t;
}              // <!-- s is no longer valid after this point, so t is pointing nowhere

【讨论】:

  • 在工作代码中,我将s初始化为*s,这只是另一个指针。并且对其进行的操作与在 s[100] 上进行的操作相同。我明白数组声明在函数的本地范围内,但是指针是否具有全局范围?
  • 没有。但是,您从未向我们展示过s 是如何在工作代码中初始化的。我假设您已经分配了内存(通过malloc() 等)——在这种情况下,范围与它无关。 malloc()-ed 内存存在,直到你调用 free()
  • 嘿!没事儿!代码中没有使用 malloc() 和其他函数。但问题是,为什么要初始化 int *s 然后再做 t=s;并返回工作正常吗?这不也是一个局部变量吗?还是定义一个指针使其全局可用?
  • 没有。同样,您从未展示过 int *s 是如何初始化的。如果它未初始化,并且您很幸运能够使用它的内容,那么那是随机机会。使用未初始化的指针,例如在函数退出后访问局部变量的空间,是未定义的行为。在某些情况下,它可能会起作用,而在其他情况下,破损更为明显。如果int *s 指向一个本地数组,那么代码布局的差异,或者调用顺序,或者月相,或者任何东西都可能导致意外的“好”行为。
  • int * myfunc(int *x, int *y, int n) { int *s,i,*t; for(i=0;i&lt;n;i++) s[i]=x[i]+y[i]; t=s; return t; } 这行得通!使用此代码编辑问题
【解决方案2】:

在不起作用的代码中,s[100] 是堆栈上的一个数组,当函数返回时超出范围。在工作代码中,您没有显示s 是如何分配的,但可能是malloc 或其他一些非堆栈分配。

一般来说,您不应该返回指向堆栈变量的指针,因为一旦函数返回,堆栈变量就会被覆盖。

PS。已经获得了真正的编译器:)

【讨论】:

  • 在工作代码中,我将s初始化为*s,这只是另一个指针。并且对其进行的操作与在 s[100] 上进行的操作相同。我明白数组声明在函数的本地范围内,但是指针是否具有全局范围?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-27
  • 1970-01-01
  • 2011-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-27
相关资源
最近更新 更多