Copy section of an array into a std::vector in C++ - c++

Hello im wondering if its possible to copy a section of an array whilst initializing a vector.
For example I have tried
UINT16 myarray[] = { 0,1,2,3,4,5,6, ..., n };
std::vector<UINT16> myvect(myarray[3], myarray[3] + 16);
This kind of works however I seem to get more data than i intended. Is this the correct usage?

The way is to pass iterators, not values
std::vector<UINT16> myvect(myarray + 3, myarray + 3 + 16);

UINT16 myarray[] = { 0,1,2,3,4,5,6, ..., n };
std::vector<UINT16> myvect(myarray[3], myarray[3] + 16);
This uses myarray[3] which is 3 and myarray[3] + 16 which is 19 as arguments to the myvect constructor. Which in turn sets up myvect to contain 3 elements, all with the value 19.
If you want a copy of the 16 elements starting at index 3, you can do it like this:
std::vector<UINT16> myvect(&myarray[3], &myarray[3 + 16]);

Here is a different (more verbose) way:
uint16_t myarray[] = { 0, 1, 2, 3, 4, 5, 6, ..., n };
constexpr auto arr_size = sizeof(myarray) / sizeof(myarray[0]);
constexpr auto copy_start = std::min< size_t >(3, arr_size);
constexpr auto copy_count = 19;
constexpr auto copy_end = std::min< size_t >(copy_start + copy_count, arr_size);
vector< uint16_t > myvect(std::next(myarray, copy_start), std::next(myarray, copy_end));
Instead of UINT16 you can use uint16_t type from C++11 onwards: Fixed width integers (if your compiler supports it)
If your values are available at compile time, then you can use compile time constants(constexpr) to calculate the helper variables. Otherwise const should be used.
Standard algorithms can be used also on arrays so providing an offset to std::next can be used to get the n-th element of an array.

Related

Calculating an array's number of elements... Able to refer to its index values by just stating the return type? What? How? Why? (C++)

I am learning how to calculate the size and number of elements in an array and came across a question. In a tutorial I see
we can calculate the number of elements in an array as follows ...
int array_variable [] = {1, 5, 8, 10};
int array_variable_number_of_elements = sizeof(array_variable) / sizeof (int);
I am aware and fully understand why you could replace
sizeof (int);
with
sizeof (array_variable[0]); // or use any index value from the array_variable
The video appears to suggest using just int is good practice which I don't understand. The computer obviously isn't psychic and int is simply a data type. What happens when there are two int type arrays in the same function? Why does this work? Does this work because it is in the same line as the following?
int array_variable_number_of_elements = sizeof(array_variable)
Thanks :)
Second approach is better and more generic, when you need to change the type of array int to char, you don't have to edit second line at all.
char array_variable [] = {'a', 'b', 'c' }; //changed this line only
int array_variable_number_of_elements = sizeof(array_variable) / sizeof
(array_variable[0]);
To answer your below comment;
above lines you can interpret like below;
int array_variable = {1, 2, 3, 4, 5 };
int array_variable_number_of_elements = sizeof(array_variable) / sizeof ( int);
// ^^^^^^^^^ ^^^^ ^^^
// array_variable_number_of_elements = 20 / 4 ; // 20 / 4 = 5
total array size in bytes 20 and size of int is 4 bytes in my system;
total number of elements in array is 5;

Strange array initialization (porting from C to C++) [duplicate]

What is the meaning of following Code? Code is from the regression test suite of GCC.
static char * name[] = {
[0x80000000] = "bar"
};
In C99 you can specify the array indices to assigned value, For example:
static char * name[] = {
[3] = "bar"
};
is same as:
static char * name[] = { NULL, NULL, NULL, "bar"};
The size of array is four. Check an example code working at ideaone. In your code array size is 0x80000001 (its an hexadecimal number).
Note: Uninitialized elements initialized with 0.
5.20 Designated Initializers:
In ISO C99 you can give the elements in any order, specifying the array indices or structure field names they apply to, and GNU C allows this as an extension in C89 mode as well. This extension is not implemented in GNU C++.
To specify an array index, write [index] = before the element value. For example,
int a[6] = { [4] = 29, [2] = 15 };
is equivalent to
int a[6] = { 0, 0, 15, 0, 29, 0 };
One more interesting declaration is possible in a GNU extension:
An alternative syntax for this which has been obsolete since GCC 2.5 but GCC still accepts is to write [index] before the element value, with no =.
To initialize a range of elements to the same value, write [first ... last] = value. For example,
int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };
Note: that the length of the array is the highest value specified plus one.
Additionally, we can combine this technique of naming elements with ordinary C initialization of successive elements. Each initializer element that does not have a designator applies to the next consecutive element of the array or structure. For example:
int a[6] = { [1] = v1, v2, [4] = v4 };
is equivalent to
int a[6] = { 0, v1, v2, 0, v4, 0 };
Labeling the elements of an array initializer is especially useful when the indices are characters or belong to an enum type. For example:
int whitespace[256] = { [' '] = 1, ['\t'] = 1, ['\h'] = 1,
['\f'] = 1, ['\n'] = 1, ['\r'] = 1
};
It's called designated initializer which is introduced in C99, gcc also supports it in GNU89 as an extension, see here for detail.
int a[6] = { [4] = 29, [2] = 15 };
is equivalent to
int a[6] = { 0, 0, 15, 0, 29, 0 };
It's a C99 designated initializer. the value in brackets specifies the index to receive the value.

Reverse channel values from 1D array

I have a 1D array float64 arr[60] being used to store voltage values from a DAQ. The array is populated as such:
10 SAMPLES_PER_CHANNEL, 6 CHANNELS, grouped by channel
transducer_0 transducer_1 ... transducer_6
[0, 1 ..., 9, 10, 11 ..., 19 ... 50, 51 ..., 59]
I would like to store this data into a 1D array of pointers and to pass to a function whose definition is: bool func2(int samples, double* const* arr2)
I have asked a similar question in this post to which the accepted solution given by #Yakk was:
template<size_t stride, class T, size_t N, size_t count = N/stride>
std::array<T*, count> make_2d( T(&raw)[N] ) {
std::array<T*, count> retval;
for (size_t i = 0; i < count; ++i)
retval[i] = raw + i*stride;
return retval;
}
I am looking for help to generate the argument double* const* arr2 for func2() which is the reverse order of the values stored in the channels. E.g.
[channel 0] [channel 1] [channel 5]
{val 9, val 8 ...val 0}, {val 19, val 18 ...val 10}, ...
The input can either be the initial 1D array, or the 1D array of pointers as constructed through the templated make_2d() function. I'm wondering what the most efficient means to do this is as the array is being updated at a rate of 5000Hz. I'm hoping there is a way which I won't have to copy values from the input array, though I am more interested in time efficiency then space efficiency.
Currently I am creating a second array of pointers and copying the reverse channel values in.
// DOF == 6, SAMPLES_PER_CHANNEL = 10
double ch0[SAMPLES_PER_CHANNEL];
double ch1[SAMPLES_PER_CHANNEL];
double ch2[SAMPLES_PER_CHANNEL];
double ch3[SAMPLES_PER_CHANNEL];
double ch4[SAMPLES_PER_CHANNEL];
double ch5[SAMPLES_PER_CHANNEL];
double* data_rev[DOF] = {
ch0, ch1, ch2, ch3, ch4, ch5};
// generate reversed order array
for (int i = DOF - 1; i > 0; --i) {
for (int j = SAMPLES_PER_CHANNEL - 1; j > 0; --j) {
data_rev[DOF - 1 - i][SAMPLES_PER_CHANNEL - 1 - j] = static_cast<double>(data[(i*10)+j]);
}
}
If I understand you correctly, what you want is not possible:
You cannot pass an array of pointers to func2 that makes it appear as if the samples would be in reversed order (I assume, you can't modify func2), but as long as you are not working on a very low power machine, something like this is dirt cheap (both in time and space overhead):
double arr[60];
std::array<double,60> tmp;
int main() {
auto t = make_2d<10>(tmp);
std::reverse(t.begin(), t.end());
while (true) {
readData(arr, 60);
reverse_copy(begin(arr),end(arr), begin(tmp));
func2(60, t.data());
}
}

How do I make a C++ function implicitly convert a list of ints into a vector parameter?

I am working on a library whose functions commonly take a vector type (__v4si, or a vector of 4 signed ints) as a parameter. (Note that so far this has nothing to do with the C++ STL vectortemplate class; this is a more primitive construct used to let the compiler generate vectorized SIMD code.)
In my C code I customarily call a wrapper macro that takes a list of int arguments and initializes a __v4si like so:
#define MakeIndex(dims...) ((__v4si){ dims })
This of course works fine in C++ too, but I would like to take advantage of C++'s more expressive type system to clean up calls to my libraries APIs. For example, where I now write something like:
long idx = IndexDotProduct(MakeIndex(1, 2, 3), MakeIndex(4, 5, 6, 7));
which macro-expands to:
long idx = IndexDotProduct(((__v4si){1, 2, 3}), ((__v4si){4, 5, 6, 7}));
I would like instead to be able to write something along the lines of:
long idx = IndexDotProduct({1, 2, 3}, {4, 5, 6, 7});
So, essentially (I think) I want to define a class that is just syntactic sugar around the primitive __v4si type, but that has an implicit cast operator for the list initializer.
How do I do that in C++ 11?
Solution
Here is a formulation that works for both C and C++ code (now using more verbose names as copied and pasted from my library header files):
typedef struct vMAT_Index {
__v4si v;
#ifdef __cplusplus
vMAT_Index(__v4si v) : v(v) { }
vMAT_Index(int v0 = 0, int v1 = 0, int v2 = 0, int v3 = 0) : v((__v4si){ v0, v1, v2, v3 }) { }
#endif
} vMAT_Index;
#define vMAT_MakeIndex(dims...) ((vMAT_Index){ .v = { dims } })
static inline long
vMAT_Index_dot(vMAT_Index a,
vMAT_Index b)
{
__v4si c = a.v * b.v;
return (long)c[0] + c[1] + c[2] + c[3];
}
In C code you still use the helper macro like this:
long idx = vMAT_Index_dot(vMAT_MakeIndex(1, 2, 3), vMAT_MakeIndex(4, 5, 6, 7));
But now in C++ you can just write:
long idx = vMAT_Index_dot({ 1, 2, 3 }, { 4, 5, 6, 7 });
Thanks to nosid for providing the essential answer!
Use implicit constructors to automatically create a vector object from a brace-initializer list:
struct vector
{
vector(__v4si v);
vector(int i0, int i1, int i2, int i3);
};
long IndexDotProduct(vector lhs, vector rhs);
long idx = IndexDotProduct(((__v4si){ 1, 2, 3 }), { 4, 5, 6, 7 });

C++ casting static two-dimensional double array to double**

I have such matrix in my program:
double m[3][4] =
{
{2, 4, 5, 7},
{4, 5, 1, 12},
{9, 12, 13, -4}
};
And I'd like to cast it to double** type.
I've already tried simple double** a = (double**)m;, but it doesn't work (when I try to read any value, I get "Access violation reading location 0x00000000.", which means I'm trying to read from NULL adress.
I found almost working solution:
double *b = &m[0][0];
double **c = &b;
It works when I read field c[0][any]
But same NULL adress reading problem occurs, when I try to read value from field c[1][0].
What is the proper way to cast my double m[3][4] array to type double**?
edit:
You say that's impossible. So I'll change a problem a little bit. How can I pass two-dimensional double array as a parameter to a function? My function has prototype:
void calculate(double **matrix, int n); //where matrix size is always n by n+1
And it's working fine with dynamically-allocated arrays. I doubt that only way to make it work is allocating new dynamical array and copy original static array one element by another...
You can't.
The notation double** refers to an array of pointers. You don't have an array of pointers, you have an array of arrays of doubles.
You can't just cast the array. You are going to have to create something like this:
double m[3][4] =
{
{2, 4, 5, 7},
{4, 5, 1, 12},
{9, 12, 13, -4}
};
double *marray[3] = {m[0],m[1],m[2]};
calculate(marray,3);
Or you can use a loop:
const size_t n = 3;
double *marray[n];
for (size_t i=0; i!=n; ++i) {
marray[i] = m[i];
}
calculate(marray,n);
When you write
double m[3][4]
{
{2, 4, 5, 7},
{4, 5, 1, 12},
{9, 12, 13, -4}
};
The compiler actually creates an array of doubles as if you had written
double _m[] = {2, 4, 5, 7, 4, 5, 1, 12, 9, 12, 13, -4};
However, thanks to C/C++ type system, the compiler remembers that m's type
is double [3][4]. In particular it remembers the sizes 3 and 4.
When you write
m[i][j]
the compiler replaces it by
_m[i * 4 + j];
(The 4 comes from the second size in double [3][4].) For instance,
m[1][2] == 1 and _m[1 * 4 + 2] == _m[6] == 1 as well.
As others said, a double** is a different type which doesn't carry the
sizes with it. To consider double** a as a 3 x 4 matrix, a[0], a[1] and
a[2] must be pointers to double (that is, double*) pointing to the
first element of the corresponding row. You can achieve this with
double* rows[] = { &m[0][0], &m[1][0], &m[2][0] };
double** a = &rows[0];
A simple cast doesn't create the variable rows above. Let me present other
alternative (but equivalent) ways to define rows
double* rows[] = { &m[0][0], &m[0][0] + 4, &m[0][0] + 2 * 4};
double* rows[] = { &_m[0], &_m[4], &_m[2 * 4]};
As you can see, only the second size (i.e. 4) is necessary. In general, for
multi-dimensional arrays, all sizes but the first are required. For this
reason a 1-dimensional array
double x[4] = { 1, 2, 3, 4 };
can be implicitly converted to a double*
double* y = x;
Using this fact we can also write
double* rows[] = { _m, _m + 4, _m + 2 * 4};
Indeed, _m is converted to a double* pointing to m[0]. Then, in _m + 4,
_m is is converted to a double* pointing to m[0] and to this pointer
it's added 4. Hence, _m + 4 is a pointer the fourth double following
_m[0], which is _m[4] and so on.
So far I have explained why you cannot cast a double [3][4] (or any other sizes) to a double**. Now, I'shall show, in your particular case, how calculate can be defined.
template <int N>
void calculate(double (&m)[N][N+1]) {
// use m as a double[N][N+1]
}
You call
calculate(m);
and the compiler will deduce the size N for you. In general (i.e, when the second dimension is not the N + 1) you can write
template <int N, int M>
void calculate(double (&m)[N][M]) {
// use m as a double[N][M]
}
If you're always using arrays (no pointers) for initialization, and you are able to avoid the pointer stuff in your calculate function, you might consider the following option, which uses size deduction by templates.
template<int m, int n>
void doubleFunc(double (&mat)[m][n])
{
for (auto i = 0; i < m; i++)
{
for (auto j = 0; j < n; j++)
{
std::cout << mat[i][j] << std::endl;
}
}
}
It worked during my quick test.
double m[3][4] =
{
{2, 4, 5, 7},
{4, 5, 1, 12},
{9, 12, 13, -4}
};
doubleFunc(m);
You can pass a 2d array as a function parameter:
void calculate(double matrix[][y], int n);
Until variable-length arrays are in the C++ standard, your choices include:
If your compiler supports variable-length arrays as an extension, you can likely pass them with a function declaration such as void foo(std::size_t n, double a[][n+1]). Note that the compiler likely requires n to be passed before a parameter declaration that uses n or requires some special syntax.
You can pass a double * and do index arithmetic manually in the function: void foo(std::size_t n, double *a) { … a[row*(n+1) + column] … }
You can create a class the implements variable-length arrays by doing the index arithmetic in its accessor functions.
You can allocate space for n pointers to double, fill those pointers with pointers to each row of the array, and pass the address of the space.