在C ++中将数组传递给函数时如何避免堆栈溢出?

时间:2016-04-26 14:23:46

标签: c++ arrays parameter-passing stack-overflow open-array-parameters

我正在编写一个代码,通过将指针传递给第一个位置将数组传递给函数。在该函数中,使用了部分数组。这会产生不安全的情况,因为如果调用者函数没有正确地猜测数组的最大大小,被调用者函数可以写入超过数组大小并且可能发生堆栈溢出。我正在考虑解决这个问题,并考虑使用函数模板并将数组作为参考传递,如本例所示。

modifyArray.h

#define MAXSIZE 10

class modifyArray
{    
public:
    void create();

    void unsafeFunction(double*);

    template<int N>
    void safeFunction(double (&array)[N] );

private:
    int computeLength();
};

modifyArray.cpp

#include <iostream>
#include "modifyArray.h"

int modifyArray::computeLength()
{
    return 11;
}

void modifyArray::create()
{
    double testarray[MAXSIZE];
    unsafeFunction(testarray);    
    safeFunction(testarray);
}

void modifyArray::unsafeFunction(double* array)
{
    int operatingSize = computeLength();
    for(int i = 0; i < operatingSize; i++) {
        array[i] = i*i;
    }
}

template<int N>
void modifyArray::safeFunction(double (&array)[N] )
{
    int operatingSize = computeLength();
    std::cout<< "Max size" << N <<std::endl;
    if(operatingSize > N) return; // Return or raise an exception

    for(int i = 0; i < operatingSize; i++) {
        array[i] = i*i;
    }
}

的main.cpp

#include "modifyArray.h"    

int main(int argc, const char * argv[]) {    
    modifyArray C;    
    C.create();
    return 0;
}

我正在寻找一种对现有代码具有微创性的解决方案。在这里,我只需添加一个模板语句,将参数从double *更改为reference,并插入if语句来检查大小。我不想做大改写。另外,我不想使用动态分配,向量或std :: array,主要是因为性能原因。这是数值模拟代码中的低级函数,性能非常重要。有更好的解决方案吗?做我正在做的事情有陷阱吗?

1 个答案:

答案 0 :(得分:4)

如果你真的想使用原始数组,并且想要安全地修改数组的所有元素而不用走路,那么你可以通过引用传递数组,然后使用range based for loop

tmeplate <typename T, typename Function, std::size_t N>
void do_work(T (&arr)[N], Function f)
{
    for (auto & e : arr)
        e = f();
}

以上将把调用函数的结果应用于数组的每个元素,并保证保持在数组的边界内。您可以像

一样使用它
int main()
{
    int arr[10];
    do_work(arr, []() { static int i = 0; i++; return i * i; });
    for (auto e : arr)
        std::cout << e << " ";
}

输出:

1 4 9 16 25 36 49 64 81 100 

Live Example