【问题标题】:deleting arrays during run time in C++ to spare some memory在 C++ 运行时删除数组以节省一些内存
【发布时间】:2020-10-27 15:38:24
【问题描述】:

我有一个在微控制器上运行 C++98 版本的 C++ 脚本(无法升级)。在这个脚本中,我需要初始化两个向量,每个向量都有 405 个已经存在的元素。我尝试初始化两个数组:double a[405]= {7.05925826e+07, ...};double b [405]= {arr[0], arr[0]*arr[1]...};a[405] 定义如下:

double a[405] = {a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15], a[16], a[17], a[18], a[19], a[20], a[21], a[22], a[23], a[24], a[25], a[26], a[0]*a[0], a[0]*a[1], a[0]*a[2], a[0]*a[3], a[0]*a[4], a[0]*a[5], a[0]*a[6], a[0]*a[7], a[0]*a[8], a[0]*a[9], a[0]*a[10], a[0]*a[11], a[0]*a[12], a[0]*a[13], a[0]*a[14], a[0]*a[15], a[0]*a[16], a[0]*a[17], a[0]*a[18], a[0]*a[19], a[0]*a[20], a[0]*a[21], a[0]*a[22], a[0]*a[23], a[0]*a[24], a[0]*a[25], a[0]*a[26], a[1]*a[1], a[1]*a[2], a[1]*a[3], a[1]*a[4], a[1]*a[5], a[1]*a[6], a[1]*a[7], a[1]*a[8], a[1]*a[9], a[1]*a[10], a[1]*a[11], a[1]*a[12], a[1]*a[13], a[1]*a[14], a[1]*a[15], a[1]*a[16], a[1]*a[17], a[1]*a[18], a[1]*a[19], a[1]*a[20], a[1]*a[21], a[1]*a[22], a[1]*a[23], a[1]*a[24], a[1]*a[25], a[1]*a[26], a[2]*a[2], a[2]*a[3], a[2]*a[4], a[2]*a[5], a[2]*a[6], a[2]*a[7], a[2]*a[8], a[2]*a[9], a[2]*a[10], a[2]*a[11], a[2]*a[12], a[2]*a[13], a[2]*a[14], a[2]*a[15], a[2]*a[16], a[2]*a[17], a[2]*a[18], a[2]*a[19], a[2]*a[20], a[2]*a[21], a[2]*a[22], a[2]*a[23], a[2]*a[24], a[2]*a[25], a[2]*a[26], a[3]*a[3], a[3]*a[4], a[3]*a[5], a[3]*a[6], a[3]*a[7], a[3]*a[8], a[3]*a[9], a[3]*a[10], a[3]*a[11], a[3]*a[12], a[3]*a[13], a[3]*a[14], a[3]*a[15], a[3]*a[16], a[3]*a[17], a[3]*a[18], a[3]*a[19], a[3]*a[20], a[3]*a[21], a[3]*a[22], a[3]*a[23], a[3]*a[24], a[3]*a[25], a[3]*a[26], a[4]*a[4], a[4]*a[5], a[4]*a[6], a[4]*a[7], a[4]*a[8], a[4]*a[9], a[4]*a[10], a[4]*a[11], a[4]*a[12], a[4]*a[13], a[4]*a[14], a[4]*a[15], a[4]*a[16], a[4]*a[17], a[4]*a[18], a[4]*a[19], a[4]*a[20], a[4]*a[21], a[4]*a[22], a[4]*a[23], a[4]*a[24], a[4]*a[25], a[4]*a[26], a[5]*a[5], a[5]*a[6], a[5]*a[7], a[5]*a[8], a[5]*a[9], a[5]*a[10], a[5]*a[11], a[5]*a[12], a[5]*a[13], a[5]*a[14], a[5]*a[15], a[5]*a[16], a[5]*a[17], a[5]*a[18], a[5]*a[19], a[5]*a[20], a[5]*a[21], a[5]*a[22], a[5]*a[23], a[5]*a[24], a[5]*a[25], a[5]*a[26], a[6]*a[6], a[6]*a[7], a[6]*a[8], a[6]*a[9], a[6]*a[10], a[6]*a[11], a[6]*a[12], a[6]*a[13], a[6]*a[14], a[6]*a[15], a[6]*a[16], a[6]*a[17], a[6]*a[18], a[6]*a[19], a[6]*a[20], a[6]*a[21], a[6]*a[22], a[6]*a[23], a[6]*a[24], a[6]*a[25], a[6]*a[26], a[7]*a[7], a[7]*a[8], a[7]*a[9], a[7]*a[10], a[7]*a[11], a[7]*a[12], a[7]*a[13], a[7]*a[14], a[7]*a[15], a[7]*a[16], a[7]*a[17], a[7]*a[18], a[7]*a[19], a[7]*a[20], a[7]*a[21], a[7]*a[22], a[7]*a[23], a[7]*a[24], a[7]*a[25], a[7]*a[26], a[8]*a[8], a[8]*a[9], a[8]*a[10], a[8]*a[11], a[8]*a[12], a[8]*a[13], a[8]*a[14], a[8]*a[15], a[8]*a[16], a[8]*a[17], a[8]*a[18], a[8]*a[19], a[8]*a[20], a[8]*a[21], a[8]*a[22], a[8]*a[23], a[8]*a[24], a[8]*a[25], a[8]*a[26], a[9]*a[9], a[9]*a[10], a[9]*a[11], a[9]*a[12], a[9]*a[13], a[9]*a[14], a[9]*a[15], a[9]*a[16], a[9]*a[17], a[9]*a[18], a[9]*a[19], a[9]*a[20], a[9]*a[21], a[9]*a[22], a[9]*a[23], a[9]*a[24], a[9]*a[25], a[9]*a[26], a[10]*a[10], a[10]*a[11], a[10]*a[12], a[10]*a[13], a[10]*a[14], a[10]*a[15], a[10]*a[16], a[10]*a[17], a[10]*a[18], a[10]*a[19], a[10]*a[20], a[10]*a[21], a[10]*a[22], a[10]*a[23], a[10]*a[24], a[10]*a[25], a[10]*a[26], a[11]*a[11], a[11]*a[12], a[11]*a[13], a[11]*a[14], a[11]*a[15], a[11]*a[16], a[11]*a[17], a[11]*a[18], a[11]*a[19], a[11]*a[20], a[11]*a[21], a[11]*a[22], a[11]*a[23], a[11]*a[24], a[11]*a[25], a[11]*a[26], a[12]*a[12], a[12]*a[13], a[12]*a[14], a[12]*a[15], a[12]*a[16], a[12]*a[17], a[12]*a[18], a[12]*a[19], a[12]*a[20], a[12]*a[21], a[12]*a[22], a[12]*a[23], a[12]*a[24], a[12]*a[25], a[12]*a[26], a[13]*a[13], a[13]*a[14], a[13]*a[15], a[13]*a[16], a[13]*a[17], a[13]*a[18], a[13]*a[19], a[13]*a[20], a[13]*a[21], a[13]*a[22], a[13]*a[23], a[13]*a[24], a[13]*a[25], a[13]*a[26], a[14]*a[14], a[14]*a[15], a[14]*a[16], a[14]*a[17], a[14]*a[18], a[14]*a[19], a[14]*a[20], a[14]*a[21], a[14]*a[22], a[14]*a[23], a[14]*a[24], a[14]*a[25], a[14]*a[26], a[15]*a[15], a[15]*a[16], a[15]*a[17], a[15]*a[18], a[15]*a[19], a[15]*a[20], a[15]*a[21], a[15]*a[22], a[15]*a[23], a[15]*a[24], a[15]*a[25], a[15]*a[26], a[16]*a[16], a[16]*a[17], a[16]*a[18], a[16]*a[19], a[16]*a[20], a[16]*a[21], a[16]*a[22], a[16]*a[23], a[16]*a[24], a[16]*a[25], a[16]*a[26], a[17]*a[17], a[17]*a[18], a[17]*a[19], a[17]*a[20], a[17]*a[21], a[17]*a[22], a[17]*a[23], a[17]*a[24], a[17]*a[25], a[17]*a[26], a[18]*a[18], a[18]*a[19], a[18]*a[20], a[18]*a[21], a[18]*a[22], a[18]*a[23], a[18]*a[24], a[18]*a[25], a[18]*a[26], a[19]*a[19], a[19]*a[20], a[19]*a[21], a[19]*a[22], a[19]*a[23], a[19]*a[24], a[19]*a[25], a[19]*a[26], a[20]*a[20], a[20]*a[21], a[20]*a[22], a[20]*a[23], a[20]*a[24], a[20]*a[25], a[20]*a[26], a[21]*a[21], a[21]*a[22], a[21]*a[23], a[21]*a[24], a[21]*a[25], a[21]*a[26], a[22]*a[22], a[22]*a[23], a[22]*a[24], a[22]*a[25], a[22]*a[26], a[23]*a[23], a[23]*a[24], a[23]*a[25], a[23]*a[26], a[24]*a[24], a[24]*a[25], a[24]*a[26], a[25]*a[25], a[25]*a[26], a[26]*a[26]};

然后使用这个函数转换它们:

std::vector<double > ArrayToVector(double* arr, size_t arr_len) {
return std::vector<double>(arr, arr + arr_len);
}

std::vector<double> vec1= ArrayToVector(a,405);
std::vector<double> vec2= ArrayToVector(b,405);

将数组转换为向量会导致内存问题。我正在寻找一种在将第一个数组a[405] 转换为向量之后删除它的方法,以便为第二次数组转换腾出一些内存。我尝试使用 new 运算符,但这对我不起作用。任何其他减少内存使用的解决方案都值得赞赏。 然后我使用 a[] 和 b[] 使用这个函数计算它们的标量积:

double scalar_product(std::vector<double> a, std::vector<double> b)
{
    if( a.size() != b.size() ) // error check
    {
        //puts( "Error a's size not equal to b's size" ) ;
        return -1 ;  // not defined
    }
    // compute
    double product = 0;
    for (unsigned int i = 0; i <= a.size() - 1; i++)
        product += (a[i])*(b[i]); // += means add to product
    return product;
}

【问题讨论】:

  • 显示更多代码。 a[] 是如何定义的等等。
  • 如果内存有限,为什么需要将现有数组转换为vector?如果必须,您实际上根本不需要 ArrayToVector() 函数,因为您使用的 C++ 版本不能保证在调用该函数时不会创建临时对象。只需直接构造vectors:std::vector&lt;double&gt; vec1(a,a+405); std::vector&lt;double&gt; vec2(b,b+405);
  • 我投票结束这个问题,因为它只是对您之前的问题稍作编辑的转发:stackoverflow.com/questions/64541171/… 保留一个,并对其进行编辑以包含您拥有的所有信息。#
  • @JHBonarius 我添加了a[]的定义
  • @RemyLebeau 我将数组转换为向量,因为我需要a[]b[] 的标量积

标签: c++ c++98


【解决方案1】:

正如某些人已经在 cmets 中建议的那样,您实际上并不需要将数组转换为向量 - 只需直接使用数组即可。您需要添加的只是数组的大小作为函数的第三个参数。为此,您显然需要知道大小,但由于这是在内存预算紧张的微控制器上运行的,因此我相对确定您可以访问大小信息。所以它可能看起来像:

double scalar_product(double a[], double b[], unsigned int size)
{
    // compute
    double product = 0;
    for (unsigned int i = 0; i <= size - 1; i++)
        product += (a[i])*(b[i]); // += means add to product
    return product;
}

我假设它们的大小相同(它们应该),但即使不是,您也可以使用它来计算两个不同大小数组的(部分)标量乘积,方法是提供较短的大小。

【讨论】:

    【解决方案2】:

    您没有通过new[]动态地分配您的double[] 数组,因此它们不能被动态释放。它们被声明在自动内存中,所以只有当它们超出范围时才会被释放。

    由于您担心内存使用有限,因此您最好的选择是根本不将您的 double[] 数组转换为 std::vector&lt;double&gt;。更改您的 scalar_product() 函数,以便它可以按原样处理原始 double[] 数组,例如:

    double scalar_product(const double *a, size_t a_size, const double *b, size_t b_size)
    {
        if( a_size != b_size ) // error check
        {
            //puts( "Error a's size not equal to b's size" ) ;
            return -1 ;  // not defined
        }
        // compute
        double product = 0;
        for (size_t i = 0; i < a_size; ++i)
            product += (a[i])*(b[i]); // += means add to product
        return product;
    }
    
    double a[405] = ...;
    double b[405] = ...;
    double product = scalar_product(a, 405, b, 405);
    
    /*
    if, for some reason, you also needed to get the product of vectors,
    you can do this:
    
    double scalar_product(const std::vector<double> &a, const std::vector<double> &b)
    {
        return scalar_product(&a[0], a.size(), &b[0], b.size());
    }
    
    vector<double> a = ...;
    vector<double> b = ...;
    double product = scalar_product(a, b);
    */
    

    或者:

    double scalar_product(const double *a, const double *b, size_t n)
    {
        // compute
        double product = 0;
        for (size_t i = 0; i < n; ++i)
            product += (a[i])*(b[i]); // += means add to product
        return product;
    }
    
    double a[405] = ...;
    double b[405] = ...;
    double product = scalar_product(a, b, 405);
    
    /*
    if, for some reason, you also needed to get the product of vectors,
    you can do this:
    
    double scalar_product(const std::vector<double> &a, const std::vector<double> &b)
    {
        return (a.size() == b.size())
            ? scalar_product(&a[0], &b[0], a.size())
            : -1.0;
    }
    
    vector<double> a = ...;
    vector<double> b = ...;
    double product = scalar_product(a, b);
    */
    

    或者,如果您直接传入原始数组,而不是传入指向数组的指针,您可以让编译器为您推断数组大小:

    template<size_t a_size, size_t b_size>
    double scalar_product(const double (&a)[a_size], const double (&b)[b_size])
    {
        if( a_size != b_size ) // error check
        {
            //puts( "Error a's size not equal to b's size" ) ;
            return -1 ;  // not defined
        }
        // compute
        double product = 0;
        for (size_t i = 0; i < a_size; ++i)
            product += (a[i])*(b[i]); // += means add to product
        return product;
    }
    
    double a[405] = ...;
    double b[405] = ...;
    double product;
    
    product = scalar_product(a, b); // OK
    
    double *pa = a;
    double *pb = b;
    product = scalar_product(pa, pb); // COMPILER ERROR
    
    /*
    this approach doesn't work with vectors, so you will need a
    separate overload of scalar_product() for that...
    */
    

    或者:

    template<size_t N>
    double scalar_product(const double (&a)[N], const double (&b)[N])
    {
        // compute
        double product = 0;
        for (size_t i = 0; i < N; ++i)
            product += (a[i])*(b[i]); // += means add to product
        return product;
    }
    
    double a[405] = ...;
    double b[405] = ...;
    double product;
    
    product = scalar_product(a, b); // OK
    
    double c[404] = ...;
    double d[405] = ...;
    
    product = scalar_product(c, d); // COMPILER ERROR
    
    /*
    this approach doesn't work with vectors, so you will need a
    separate overload of scalar_product() for that...
    */
    

    否则,如果数组大小在编译时保持不变,则只需对其进行硬编码:

    const size_t ArrSize = 405;
    
    double scalar_product(const double (&a)[ArrSize], const double (&b)[ArrSize])
    {
        // compute
        double product = 0;
        for (size_t i = 0; i < ArrSize; ++i)
            product += (a[i])*(b[i]); // += means add to product
        return product;
    }
    
    double a[ArrSize] = ...;
    double b[ArrSize] = ...;
    double product = scalar_product(a, b);
    
    /*
    this approach doesn't work with vectors, so you will need a
    separate overload of scalar_product() for that...
    */
    

    【讨论】:

      【解决方案3】:

      必须动态分配数组(使用new[] 运算符)才能使用delete[] 运算符释放它。正如 cmets 所提到的,您应该发布如何创建数组,以便我们更好地了解它们是如何存储在内存中的。

      double a* = new double[size];
      // do stuff with a
      delete[] a;
      

      上面的例子是合法的,会按照你的要求去做。

      【讨论】:

      • 如何初始化数组的元素?
      • 使用new[],你不能用C++98中new[]语句中的值来初始化数组。您必须为每个元素单独使用a[index] = ...,否则使用另一个数组中的memcpy()/std::copy()
      猜你喜欢
      • 1970-01-01
      • 2019-06-20
      • 1970-01-01
      • 2017-11-20
      • 1970-01-01
      • 1970-01-01
      • 2017-05-13
      • 2011-09-18
      • 2012-09-06
      相关资源
      最近更新 更多