This is not modern-day C++, and obviously you should not be deleting your return value.
im trying to copy values from row row_num of the 2D array the_array
into the 1D array
First off, the_array in this context, being defined as a raw poiner and used for pointer arithmetic, is a 1D representation of a 2D array -- better be accurate in our description.
the error im getting [...] is : operand of '*' must be a pointer
Ok, so this line:
*row = *(*(the_array + row_num) + i);
is kind of a mess. I think I see where you were going with it, but look, you're dereferencing (using * to the left of an expression) twice for no reason, which BTW causes the error. Remember we said the_array is a raw pointer, being treated as a 1D array. Hence, you can use this type of pointer arithmetic, let's say inside the parenthesis, and then dereference it just once. Your expression above takes the resultant address of (the_array + row_num), dereferences it to get the double within this cell of the array, and then adds i to the double value itself and then tries to dereference this sum of a double and int i -- which is a temporary variable of type double, not much of a pointer. This here is probably the line you were aiming for:
*row = *(the_array + row_num * col_size + i);
Because the 2D data is spread contagiously in memory, row by row, consecutively, you need to multiply the row index like this by the row size (which is also the column count, and I take it that col_size is actually that, otherwise you have no way of traversing between rows) to "skip between the rows" and finally add the current cell index i to get to the specific cell inside the row. Then, like we said, dereferene the whole thing.
Beyond the compilation issue and address calculation, you should at least keep address of row before incrementing it in the loop so you could be returning it and not the pointer past-the-end of the row. In keeping as much as possible with your original function, you can do it using a second pointer like this:
double* get_row(double *the_array, int row_num, int col_size) {
double* row = new double[col_size];
double* rowPtr = row;
for (int i = 0; i < col_size; i++) {
*rowPtr = *(the_array + row_num * col_size + i);
rowPtr++;
}
return row;
}
I'm trying to keep this as closest as possible to your version, so you could see the difference from what you did. Many things are better done differently, for example why not use the [] operator in the first place like this row[i] = *(the_array + row_num * col_size + i); and then get rid of the second pointer altogether? No real need for doing ++ there as a second line in the loop if you're iterating over i as it is. Another example is did you have to allocate or could you just return a pointer to the existing array but in the right place?
Too important to not mention here is that in almost any scenario you really shouldn't be returning a raw pointer like this, as it could too easily lead to unclear intent in the code, as to who owns the allocation (and is responsible to delete it eventually) and raises the issue of how to prevent memory-leak in case of an exception? The preferred solution is to be using smart pointers, such as std::unique_ptr, an instance of which wraps the raw pointer and makes it so you're going to have to be very explicit if you'll want to just throw that piece of memory around in an unsafe way.
double *the_arrayis not a 2d arraydelete[] row; return row;is an clear and immediate red flag. You can't use something you've just deleted.std::array,std::vector,std::copy,std::unique_ptr,std::shared_ptr, range basedforloops, etc. Not manual memory management, C-style arrays, raw pointers. C++ should be taught as C++17 first, then the ugly legacy stuff that we all try to avoid, later (if needed at all). Code like this makes me sad.decltype(array_name)will never yield a pointer.