Hello I'm trying to port some old code to new standards. I have a
std::complex<double> **data_2D;
And I need to set a portion of that to zero. I used to do with:
memset( &( data_2D[dims[0]-delta][0] ), 0, delta*dims[1]*sizeof( std::complex<double> ) );
which gives this warning:
clearing an object of non-trivial type 'class std::complex<double>'; use assignment or value-initialization instead
How do I change that memset with a std::fill
? I got lost in double pointers...
Here is a minimale example:
#include <iostream>
#include <complex>
#include <string.h>
int main() {
unsigned int dims[2]={10,10};
std::complex<double> *cdata_ = new std::complex<double>[dims[0]*dims[1]];
std::complex<double> **data_2D;
data_2D= new std::complex<double> *[dims[0]];
for( unsigned int i=0; i<dims[0]; i++ ) {
data_2D[i] = cdata_ + i*dims[1];
for( unsigned int j=0; j<dims[1]; j++ ) {
data_2D[i][j] = 0.0;
}
}
unsigned int delta=5;
memmove( &( data_2D[0][0] ), &( data_2D[delta][0] ), ( dims[1]*dims[0]-delta*dims[1] )*sizeof( std::complex<double> ) );
memset( &( data_2D[dims[0]-delta][0] ), 0, delta*dims[1]*sizeof( std::complex<double> ) );
return 0;
}
You don't need to change anything about the pointers. If you use std::fill_n
you only need to be careful of the arguments being in a different order and that the number of elements, not the number of bytes, is expected:
std::fill_n( &( data_2D[dims[0]-delta][0] ), delta*dims[1], 0 );
However, &...[0]
has the same effect as implicit array-to-pointer decay, so it can be written as well as
std::fill_n( data_2D[dims[0]-delta], delta*dims[1], 0 );
And I don't really see the point in having data_2D
in the first place. Just index cdata_
directly:
std::fill_n( cdata_ + (dims[0]-delta)*dims[1], delta*dims[1], 0 );
Or if you want an interface to index by row and column, wrap cdata_
in a class with a member function indexing the array by 2D indices.
I would also recommend replacing new
if you are already modernizing. It should be a std::vector
instead.