【问题标题】:how can deal with float *array如何处理 float *array
【发布时间】:2021-10-31 16:14:24
【问题描述】:

我有这样的数组声明

第一种方式

int size=256*10;
float *array=(float*)malloc(size * sizeof(float));
for(int i=0;i<2398;i++)
     data[i]=data[i]*900;

当我使用这个为什么在声明中我的代码运行时没有错误但是

当我像这样使用数组作为常量值时:

第二种方式

float array[]={120.0, 160.0, 255.0, 216.0, 255.0, 224.0, 0.0, 16.0, 
74.0, 70.0, 73.0, 70.0, 0.0, 1.0, 1.0};

即使我以第一种方式获取数组输出并将其定义为第二种方式,我也没有从代码中得到所需的内容?!! 我认为以第二种方式定义一个数组是正确的并且等同于第一种定义?! 声明与第一种方式等效的数组的正确方法是什么?

【问题讨论】:

  • 正确的方法是使用std::vector
  • 请为该错误创建一个minimal reproducible exampledouble array[]={120.0, 160.0, 255.0, 216.0, 255.0, 224.0, 0.0, 16.0, 74.0, 70.0, 73.0, 70.0, 0.0, 1.0, 1.0}; 应该可以工作。
  • 天啊!你有 2560 个常量值吗?
  • "声明数组的正确方法是什么" -- 对于初学者,有错误的行没有声明数组;您的数组在以float 开头的行上声明。然后有一个问题,你似乎有两种不同的初始化——提供一个值列表和动态分配。你两个都需要吗?为什么要在这里使用动态分配(以及为什么要使用malloc() 而不是newmake_unique)?
  • 也许问题不在你想的地方。这就是为什么展示一个最小的可重现示例很重要。如果您的问题可能出在我们看不到的代码中,那么我们无能为力。

标签: c++ arrays


【解决方案1】:

这两种方法都可以创建有效的数组,如果您注意对象的生命周期,您可以非常灵活地使用它们。区别在于:

  • malloc 动态分配内存,直到程序在 malloc 返回的地址上显式调用free()。典型的用例之一是在函数中分配和初始化一些存储,让函数返回地址。这很好:对象在动态分配的内存(new、malloc)中的生命周期是独立的范围(例如,函数)。

    相比之下,以第二种方式定义的数组一直存在,直到变量超出范围。如果它是一个全局变量,它将一直存在到程序结束。如果它是在函数中定义的,它只会在程序从函数返回或结束之前存在。这可能是你的问题。返回函数本地对象的地址并在该函数之外使用它是一个不常见的错误。警告级别足够高的较新编译器在看到此类错误时应发出警告。

  • 第二个数组是一个对象,其元素数量由初始化器指定。您可以调用sizeof(array) 并获得一个大数字,例如60。相比之下,第一个“数组”根本不是一个数组:它是一个指向数组第一个元素的指针。 对该指针调用 sizeof() 会返回该指针的大小,通常为 4 或 8,无论在指针指向的位置分配了多少内存。没有内置的方法来跟踪分配内存的大小——程序员必须将它存储在某个地方。通常,较大的程序在“翻译单元”(源文件)共享的标头中的某处有一个常量或定义,因此使用分配内存的程序部分不会超出其限制,并且分配它的部分知道多少需要。

  • 标准 C++ 没有可变长度数组:在编译时必须知道数组大小。这显然并不总是可能的。例如,大多数图像格式在文件的前几个字节中包含图像大小。读取此类图像的程序会将几个字节读取到信息结构中,然后为实际像素动态分配所需的内存。如果您想使用编译时大小的数组,您当然可以简单地定义一个足够大的用于大图片的数组,而只将其中的一部分用于较小的图片。但是您最终会得到通常会浪费空间的数组大小,因为它们对于普通图片来说太大了——但可能仍然不适合他们可能遇到的最大图片!最好使用可以在运行时确定或更改大小的数据结构,例如std::vector,或使用new() 创建的数组,或者,如果必须的话,malloc()

备注:

  1. 您没有使用整个分配的内存,这有点奇怪:您分配了 2560 个浮点数,但仅将值分配给 2398。
  2. 赋值data[i]=data[i]*900; 在赋值之前从未初始化的元素data[i] 中读取。读取未初始化的内存是verbotenkaput(“未定义行为”),程序出错。在实践中,您可能只会有有趣的浮点值,但仍然如此。不要这样做。

如果您有一个数组,您想用编译时已知的几十个值进行初始化,我强烈希望使用真正的数组。如果它需要比函数更长的寿命,可以将其设为静态并让函数返回指向它的指针。

仅当您需要大量内存(2500 个浮点数合格)或必须创建一个在编译时大小未知的数组,或必须创建未知数量的数组时,才考虑动态创建它们。

正如其他人在 cmets 中所说,实际代码将使用向量或智能指针和/或std::array。显式动态分配几乎已经成为初学者作业的领域(我不是屈尊俯就:它在那里有它的位置)或使用旧编译器的项目(不要问)。

【讨论】:

  • @chux-ReinstateMonica 好点——正确的术语是解释的一半......
猜你喜欢
  • 2017-06-13
  • 1970-01-01
  • 2022-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多