Slugger Slugger - 1 month ago 12
C++ Question

Use a pointer to the rows of 2D array to initialize its values. Why does this work?

I declare an array

square[10][10]
and I want to initialize it to contain only ones. (I already declare it to all zeros using the normal initializer but this is just so the array is not full of junk when I print it when debuggin). I can easily initialize with a double for loop but I tried to use an array of pointers to the rows of
square
. Here is my code.

#include <iostream>

using namespace std;

void initToOnes(int (*row)[10]) {
for (int *rowp = row[0]; rowp != row[0] + 100; rowp += 10) {
for (int *cs = rowp; cs != rowp + 10; ++cs)
*cs = 1;
}
}

int main()
{
int square[10][10] = {0};
int (*row)[10] = square;

initToOnes(row);
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++)
cout << square[i][j] << ' ';
cout << '\n';
}
}


Now this works, although I am not completely sure why. The function
initToOnes
takes in a pointer to blocks of 10 ints. So then, in the outer for loop of the function, shouldnt
rowp++
be enough to increment the pointer to point to the second row of ints? In other words, can I cast the same function into a double for loop that looks like this:

for (pointer rowp; rowp != row + 10; ++rowp){
// inner loop;
}


The way this function works now seems to be kindof defeating the point of having a pointer to some rows. This way (I guess) I could just send the pointer to the first entry in
square
and increment that by 10 in the outer for loop to run over the rows. Is this implementation poor and defeating the point of defining pointers to the rows? Thanks!

EDIT: The comments and answers cleared up the confusion. I declared
rowp
as a pointer to an int, so of course
++rowp
would just point to the next int instead of the next row. Here is my updated solution

#include <iostream>

using namespace std;

void initToOnes(int (*row)[10]) {
for (int (*rowp)[10] = row; rowp != row + 10; ++rowp) {
for (int *cs = *rowp; cs != *rowp + 10; ++cs)
*cs = 1;
}
}

int main()
{
int square[10][10] = {0};
int (*row)[10] = &square[0];

initToOnes(row);
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++)
cout << square[i][j] << ' ';
cout << '\n';
}
}

Answer

In the outer loop, the loop variable is an

int *rowp;

Which means that incrementing it will increment rowp to point to the next integer.

That's the end of the story. Full stop.

The fact that the area of memory that rowp points to is logically divided into a series of blocks of ten ints does not change the fundamental fact that rowp is a pointer to an int, and not an array of ten ints.

Now, if you want to do something with a pointer to ten ints:

int array[10][10];
int (*p)[10] = &array[0];

Now, you can convince yourself that incrementing p will advance it by ten ints. How to retrofit your loop to use such a pointer should be obvious. In fact, you already have the right variable passed in as a parameter. Use it.