Dynamically allocating and setting to zero an array of floats

落花浮王杯 提交于 2019-12-03 10:57:22
Thomas L Holaday

Use sizeof(float) * filter_len unless you are working in some odd implementation where sizeof(float) == sizeof(char).

memset(delay_line, 0, sizeof(float) * filter_len);

Edit: As Stephan202 points out in the comments, 0.0 is a particularly easy floating point value to code for memset since the IEEE standard representation for 0.0 is all zero bits.

memset is operating in the realm of memory, not the realm of numbers. The second parameter, declared an int, is cast to an unsigned char. If your implementation of C++ uses four bytes per float, the following relationships hold:

  • If you memset the float with 0, the value will be 0.0.
  • If you memset the float with 1, the value will be 2.36943e-38.
  • If you memset the float with 42, the value will be 1.51137e-13.
  • If you memset the float with 64, the value will be 3.00392.

So zero is a special case.

If this seems peculiar, recall that memset is declared in <cstring> or <string.h>, and is often used for making things like "***************" or "------------------". That it can also be used to zero memory is a nifty side-effect.

As Milan Babuškov points out in the comments, there is a function bzero (nonstandard and deprecated), available for the moment on Mac and Linux but not Microsoft, which, because it is specially tailored to setting memory to zero, safely omits a few instructions. If you use it, and a puritanical future release of your compiler omits it, it is trivial to implement bzero yourself in a local compatibility patch, unless the future release has re-used the name for some other purpose.

use

#include <algorithm>
...
std::fill_n( delay_line, filer_len, 0 )

The elements of a dynamically allocated array can be initialized to the default value of the element type by following the array size by an empty pair of parentheses:

float* delay_line = new float[filter_len]();

Use a std::vector instead:

std::vector<float> delay_line( filter_len );

The vector will be zero initialised.

Now that we're at it: even better would be to use the vector class.

std::vector< float > delay_line( filter_len, 0.0 );

Another option is to use calloc to allocate and zero at the same time:

float *delay_line = (float *)calloc(sizeof(float), filter_len);

The advantage here is that, depending on your malloc implementation, it may be possible to avoid zeroing the array if it's known to be allocated from memory that's already zeroed (as pages allocated from the operating system often are)

Keep in mind that you must use free() rather than delete [] on such an array.

Which is the most efficient way

memset maybe a tad faster, BUT WHO CARES!?!? Micro-optimization down to this level is a total waste of time, unless you're programming a calculator, and probably not even then.

I think the memset way is clearer, BUT I think you really had better check your man-pages for memset... I'd be suprised if your version of standard libraries has a memset function which takes a float as the second argument.

PS: The bit pattern representing zero is the same for both integers and floats... this is by design, not just good luck.

Good Luck ;-)

Cheers. Keith.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!