Why are malloc_<type> in gr::fft?

It’s not a big deal, but I’m just curious.

Why are malloc functions, malloc_complex, malloc_double, malloc_float in
gr::fft ?
I think memory allocating functions can be used in various purposes, not
only in FFT.

Is it just a workaround that
there are no more proper places (gr::analog, gr::digital, gr::blocks…)
for malloc?

Or, is it not just a simple memory allocated array,
but a special array that something happens when items are put into the
array?

Regards,
Jeon.

Hi Jeon,

you just malloc(...) when you need to; why would you, in general, need
GNU Radio to wrap that simple libc call, especially since there’s
calloc?

Or, is it not just a simple memory allocated array,
but a special array that something happens when items are put into the
array?
It’s special.
gr::fft needs these fftw_mallocs because FFTW (which is the FFT library
underneath) expects specially aligned memory, and therefore offers it’s
own fftwf_malloc; thus, we need to wrap this up. It’s an
FFTW-speciality, and shouldn’t be used for different things than memory
that FFTW works on.
When you work with fftw (which is a C library) in C++, you’ll notice
that C++ is a bit more strict than C when it comes to pointer types, and
you have to cast around the pointer type just to get it working. Since
that is a bit ugly to do in-line, there’s these malloc abstractions that
you’ve mentioned.

Generally, as we try to write beautiful C++, we don’t malloc much –
new[] might be your friend if you actually want to work with arrays.
However, GNU Radio is a bit doomed when it comes to having beautiful,
type-safe code, because the core concept of gr_buffer basically is that
buffers between blocks are just memory regions, not data of a specific
type – hence all the “ugly” pointer casting that happens in about every
work().

There’s a lot of places where malloc is really handy in our code, for
example in the DVB decoders, where structures for decoding need to
dynamically be allocated, or in the GUIs, where you often just want to
have a bit of memory representing your framebuffer. But as a rule of
thumb, you should try to avoid dynamically allocating memory manually
(using malloc) as much as possible – it’s just one of the most popular
causes for hard-to-debug bugs.

It’s often practical to use std::vector<type> myvector(number_of_elements) instead – it does the allocation for you,
allows for resizing, and you can, just like with malloc, get the address
of the first element ( &(myvector[0]) ) . As a bonus, myvector[x]
always actually has the right type, and you don’t need to first cast the
return value of malloc to a pointer of whatever you want to have.
If you don’t need the resizing of std::vector, just the dynamic
allocation, std::array is also awesome; both being STL containers
offer a great deal of functionality that you’d have to implement
yourself if you just go a C-style array in some malloc’ed memory.

Best regards,
Marcus

On Thu, Apr 23, 2015 at 4:53 AM, Marcus Müller
[email protected]
wrote:

gr::fft needs these fftw_mallocs because FFTW (which is the FFT library
might be your friend if you actually want to work with arrays.
as much as possible – it’s just one of the most popular causes for
great deal of functionality that you’d have to implement yourself if you
just go a C-style array in some malloc’ed memory.

Best regards,
Marcus

I’ll point people to the use of volk_malloc instead of malloc or new.
See
the bottom of this page:

http://libvolk.org/doxygen/concepts_terms_and_techniques.html

This provides us with control over the alignment of the allocated
memory,
which sets us up nicely for VOLK calls.

For those “but actually’s” in the works, I know there are various other
methods out there and growing support in the compilers and C/C++
standards
for this type of thing. The implementation of volk_malloc makes use of
those when possible but provides the abstracted interface to make sure
that
the right thing™ is done for the given platform.

Still, we don’t use this dynamically as Marcus said. If we need to
allocate
some memory in our blocks, we try to set this up in the constructor so
that
it’s allocated once at startup (and then volk_free is called in the
dtor).

Tom

Marcus,

Thank you for your detailed explanation.

Now, I can see that I can use an ordinary malloc if there is no
specially
aligned memory.

Thanks.

2015-04-23 17:53 GMT+09:00 Marcus Müller [email protected]: