如果我们在c ++中使用static关键字删除[-Wreturn-local-addr](警告:返回的局部变量的地址),这样可以吗?

时间:2016-07-31 19:44:13

标签: c++ arrays pointers

我有一个功能:

int* sumCalc(int *p1, int *p2, int n1, int n2)
{
    int sum[100] = {0};// = new int[n1+n2];
    for(int i = 0; i < n1+n2; ++i)
    {
        sum[i] = p1[i] + p2[i];
    }
    return sum;
}

我通过写:

从main()调用此函数
int *sum = sumCalc(p1, p2, n1, n2);

所以在这里我会得到警告。

要删除警告,我将我的int数组sum[100]更改为静态,然后我将返回总和。

int* sumCalc(int *p1, int *p2, int n1, int n2)
{
    static int sum[100] = {0};// = new int[n1+n2];
    for(int i = 0; i < n1+n2; ++i)
    {
        sum[i] = p1[i] + p2[i];
    }
    return sum;
}

将局部变量设为静态是一个好习惯吗?

如果我从堆中获取数组sum[100]的内存,那么我认为这个错误不存在。但是你能告诉我如何在这里使用new运算符并将数组的所有元素初始化为零吗?

2 个答案:

答案 0 :(得分:3)

问题是在第一个版本中,变量是从堆栈而不是堆分配的。这意味着当函数返回时,sum变量消失,你得到的是一个无处可寻的随机剩余地址。

是的,将变量声明为静态会使警告消失,但这种做法很糟糕。告诉编译器的是,无论函数被调用多少次,都只有sum变量的一个副本。这意味着如果再次调用该函数,该数组将具有相同的内容。

int array1[3] = {1, 2, 3};
int array2[3] = {2, 3, 4};

int array3[2] = {5, 6};
int array4[2] = {7, 8};

int* returned = sumCalc(array1, array2, 3, 3); 
int* gotcha = sumCalc(array3, array4, 2, 2); //Now returned is the same array as gotcha!

这可能会造成混淆,因为如果您期望returnedgotcha不同,那么您会感到惊讶。它们都会指向{12, 14}

要分配堆,您必须使用new运算符。您可以在this question中找到多种初始化数组的方法。

编辑:P.S。 - 不要忘记delete在程序结束时用new分配的指针。

答案 1 :(得分:0)

在块范围内使用时,关键字static将生成

  • sum的行为类似于函数变量
  • 它将在函数的不同调用之间共享
  • 上述情况可能并不理想。

解决方法是

  • 在主
  • 中定义int sum[100] = {0};
  • 通过将sumCalc签名修改为类似

    的方式将指针传递给它
    void sumCalc(int (*ptr)[100),int *p1, int *p2, int n1, int n2)
    // Note the return type is void
    

并将其称为

sumCalc(&sum,p1, p2, n1, n2);

总和中的循环将是:

for(int i = 0; i < n1+n2; ++i)
{
    (*ptr)[i] = p1[i] + p2[i]; 
}