Discussion:
debugger and 2d arrays
(too old to reply)
E. Inazaki
2013-03-30 18:38:01 UTC
Permalink
Hello,

I have a simple program that prints and does scalar multiplication on a
2d array. The program is split between two files, here they are:

======= The main file =====
#include <stdio.h>

int main(void) {
void scalarMultiply(int matrix[3][5], int scalar);
void displayMatrix(int matrix[3][5]);
int sampleMatrix[3][5] =
{
{7, 16, 55, 13, 12},
{12, 10, 52, 0, 7},
{-2, 1, 2, 4, 9}
};

displayMatrix(sampleMatrix);

scalarMultiply(sampleMatrix, 2);

displayMatrix(sampleMatrix);

scalarMultiply(sampleMatrix, -1);

displayMatrix(sampleMatrix);

return 0;
}


======= The functions file =======
#include <stdio.h>

void scalarMultiply(int matrix[3][5], int scalar) {
int row, column;

for(row = 0; row < 3; ++row)
for(column = 0; column < 5; ++column)
matrix[row][column] *= scalar;
}


void displayMatrix(int matrix[3][5]) {
int row, column;

for(row = 0; row < 3; ++row) {
for(column = 0; column < 5; ++column)
printf("%5i", matrix[row][column]);
printf("\n");
}
}

I'm using version 1.7 of the debugger. My problem is that if I place a break
in the main, I can view the entire contents of the array but if my break is
somewhere in the functions I can only see part of it (looks like just the first
row). Why is that and how can I examine the entire array from the functions?

TIA
eric
Hans-Bernhard Bröker
2013-03-30 19:29:06 UTC
Permalink
Post by E. Inazaki
======= The main file =====
#include <stdio.h>
int main(void) {
void scalarMultiply(int matrix[3][5], int scalar);
void displayMatrix(int matrix[3][5]);
Please don't do that (declare functions inside other functions, that
is). Header files were invented for a reason.
Post by E. Inazaki
I'm using version 1.7 of the debugger. My problem is that if I place a break
in the main, I can view the entire contents of the array but if my break is
somewhere in the functions I can only see part of it (looks like just the first
row). Why is that and how can I examine the entire array from the functions?
You can't, because neither the debugger nor your code has any idea how
many rows your matrix has, once you're inside the function you passed it
to like that.

Ultimately your Subject line is entirely misleading, because this issue
is wholly unrelated both to the debugger and to 2D arrays. The actual
issue is that all function arguments of type array like this:

void function(int foo[3]);

are totally misleading. There is no difference at all between the above
and either of the following:

void function (int foo[2000]);
void function (int foo[]);
void function (int *foo);

You can write a number between those [], but it will have no effect
besides looking different.
E. Inazaki
2013-03-30 23:36:11 UTC
Permalink
Post by Hans-Bernhard Bröker
Post by E. Inazaki
======= The main file =====
#include <stdio.h>
int main(void) {
void scalarMultiply(int matrix[3][5], int scalar);
void displayMatrix(int matrix[3][5]);
Please don't do that (declare functions inside other functions, that
is). Header files were invented for a reason.
I copied it straight out of a book, that's what the author did. I did
think it looked a little odd. Normally I'd put it outside of main or,
as you suggested, in a .h file. This was just a quick lash-up and
didn't want to bother with a .h file.
Post by Hans-Bernhard Bröker
Post by E. Inazaki
I'm using version 1.7 of the debugger. My problem is that if I place a break
in the main, I can view the entire contents of the array but if my break is
somewhere in the functions I can only see part of it (looks like just the first
row). Why is that and how can I examine the entire array from the functions?
You can't, because neither the debugger nor your code has any idea how
many rows your matrix has, once you're inside the function you passed it
to like that.
Ultimately your Subject line is entirely misleading, because this issue
is wholly unrelated both to the debugger and to 2D arrays. The actual
void function(int foo[3]);
are totally misleading. There is no difference at all between the above
void function (int foo[2000]);
void function (int foo[]);
void function (int *foo);
You can write a number between those [], but it will have no effect
besides looking different.
Is this related to the fact that C doesn't do bounds checking on arrays?
So putting a number between the [] is what, just a convenience for the
programmer?

So how is it that I can see all of the array in main()? Is it because
it was explicitly initialized there?

Finally, there must be a way to examine arbitrary array elements inside
the function, right? Take the address of the array which, I think, is
provided and then calculate the offsets by hand maybe.

Thanks,
eric
Steven Levine
2013-03-31 07:33:45 UTC
Permalink
On Sat, 30 Mar 2013 23:36:11 UTC, "E. Inazaki" <***@yahoo.com>
wrote:

Hi,
Post by E. Inazaki
Is this related to the fact that C doesn't do bounds checking on arrays?
So putting a number between the [] is what, just a convenience for the
programmer?
Not really. It more about how the debugger defaults the displayed
data when it does not have complete debug information. The debugger
is very flexible. For example, you can use the Type option in the
context menu for the data item, so change how OpenWatcom formats the
data.
Post by E. Inazaki
the function, right? Take the address of the array which, I think, is
provided and then calculate the offsets by hand maybe.
In most case, the debugger can do the math for you.

Steven
--
---------------------------------------------------------------------
Steven Levine <***@earthlink.bogus.net>
eCS/Warp/DIY etc. www.scoug.com www.ecomstation.com
---------------------------------------------------------------------
Hans-Bernhard Bröker
2013-03-31 12:28:12 UTC
Permalink
Post by E. Inazaki
Post by Hans-Bernhard Bröker
Please don't do that (declare functions inside other functions, that
is). Header files were invented for a reason.
I copied it straight out of a book, that's what the author did.
Then maybe you need a better book ;-)
Post by E. Inazaki
Post by Hans-Bernhard Bröker
You can write a number between those [], but it will have no effect
besides looking different.
Is this related to the fact that C doesn't do bounds checking on arrays?
No. It's related to the fact that C doesn't operate on arrays as a
whole. You can't assign arrays, you can't perform arithmetic on them,
and you can't pass them to functions.
Post by E. Inazaki
So putting a number between the [] is what, just a convenience for the
programmer?
Actually in the case at hand it's even less than that. It's a
misleading distraction to the programmer because it makes a claim that's
just not true.

In the long run it may be better to forget that the possibility of
putting a number in there exists.
Post by E. Inazaki
So how is it that I can see all of the array in main()? Is it because
it was explicitly initialized there?
No, it's because main() sees the definition of the actual array. Where
or not it's initialized has nothing to do with it.
Wilton Helm
2013-05-10 17:23:12 UTC
Permalink
Because of C's inability to work with arrays as a whole, I sometimes wrap an
array in a structure. If a pointer argument is typecast to be a point to
the appropriate structure, the debugger will autotmatically view it
correctly.

Granted, structures are still somewhat second class citizens, in that you
can't do arithmetic, etc. on them. But you can assign the contents of one
structure to another, which is a lot more than you can do with array
pointers or even actual arrays.

Wilton

Paul S. Person
2013-03-31 17:13:02 UTC
Permalink
On Sat, 30 Mar 2013 18:36:11 -0500, "E. Inazaki"
Post by E. Inazaki
Finally, there must be a way to examine arbitrary array elements inside
the function, right? Take the address of the array which, I think, is
provided and then calculate the offsets by hand maybe.
1) highlight the variable, right-click it and choose "Watch".
2) in the Watch window,
a) highlight the variable, right-click it and choose "Type"
b) on the popup menu, choose "Array"
c) enter the last valid index in the End box of the Enter Index
Range dialogue

This will produce a linear display of the memory pointed to by the
variable as an array from 0 to the end value you specified. It will do
this pretty much no matter what the variable is; I tested it while
typing the above on a NULL pointer and got 12 "array" members in the
Watch window. They didn't show anything, of course, since even the
debugger cannot read from 0:0, but they were listed and, for real
data, whatever is in those locations will be shown.

I have used this many times but only for 1D arrays. It is possible
that your 2D array will be presented as a 1D array, although there may
be a way around that as well; you need to do some experimenting with
wdw.

Note: I was using the current wdw (1.9), but I am reasonably sure that
wdw 1.7 worked the same way. As, I suspect, did all the other
versions.

Note: the same steps work with wd. These would be the 32-bit Windows
versions, as I am using Windows XP.
--
"Nature must be explained in
her own terms through
the experience of our senses."
E. Inazaki
2013-03-31 18:06:55 UTC
Permalink
Post by Paul S. Person
On Sat, 30 Mar 2013 18:36:11 -0500, "E. Inazaki"
Post by E. Inazaki
Finally, there must be a way to examine arbitrary array elements inside
the function, right? Take the address of the array which, I think, is
provided and then calculate the offsets by hand maybe.
1) highlight the variable, right-click it and choose "Watch".
2) in the Watch window,
a) highlight the variable, right-click it and choose "Type"
b) on the popup menu, choose "Array"
c) enter the last valid index in the End box of the Enter Index
Range dialogue
This will produce a linear display of the memory pointed to by the
variable as an array from 0 to the end value you specified. It will do
this pretty much no matter what the variable is; I tested it while
typing the above on a NULL pointer and got 12 "array" members in the
Watch window. They didn't show anything, of course, since even the
debugger cannot read from 0:0, but they were listed and, for real
data, whatever is in those locations will be shown.
I have used this many times but only for 1D arrays. It is possible
that your 2D array will be presented as a 1D array, although there may
be a way around that as well; you need to do some experimenting with
wdw.
Note: I was using the current wdw (1.9), but I am reasonably sure that
wdw 1.7 worked the same way. As, I suspect, did all the other
versions.
Note: the same steps work with wd. These would be the 32-bit Windows
versions, as I am using Windows XP.
Outstanding! I was going to go back to the help file to see if it was
covered but you saved me a bunch of work. I should probably go back
into the doc anyway.

Thanks,
eric
E. Inazaki
2013-04-01 18:42:29 UTC
Permalink
Post by Paul S. Person
On Sat, 30 Mar 2013 18:36:11 -0500, "E. Inazaki"
Post by E. Inazaki
Finally, there must be a way to examine arbitrary array elements inside
the function, right? Take the address of the array which, I think, is
provided and then calculate the offsets by hand maybe.
1) highlight the variable, right-click it and choose "Watch".
2) in the Watch window,
a) highlight the variable, right-click it and choose "Type"
b) on the popup menu, choose "Array"
c) enter the last valid index in the End box of the Enter Index
Range dialogue
This will produce a linear display of the memory pointed to by the
variable as an array from 0 to the end value you specified. It will do
this pretty much no matter what the variable is; I tested it while
typing the above on a NULL pointer and got 12 "array" members in the
Watch window. They didn't show anything, of course, since even the
debugger cannot read from 0:0, but they were listed and, for real
data, whatever is in those locations will be shown.
I have used this many times but only for 1D arrays. It is possible
that your 2D array will be presented as a 1D array, although there may
be a way around that as well; you need to do some experimenting with
wdw.
Note: I was using the current wdw (1.9), but I am reasonably sure that
wdw 1.7 worked the same way. As, I suspect, did all the other
versions.
Note: the same steps work with wd. These would be the 32-bit Windows
versions, as I am using Windows XP.
Just tried it, that was awesome. For the 2d array, I did as you described
using the range for the first index. The watch window displayed a nested
list, where the second dimension is nested in the first. I.e. using
something like a[3][5], and specifying zero as the start and two as the end
I get something like:
a
x |- [0] [array]
| |-[0] 1
| |-[1] 3
| |-[2] 5
| |-[3] 7
| |-[4] 7
o |-[1] [array]
o |-[2] [array]

I should see how 3d arrays work.

Thanks again,
eric
Loading...