0

I'm seeing some very strange behavior when using 64 bit integers in a little program I've written. My program does the following...

  1. create 2D long long int array (X by Y)
  2. Initialize all array indice values from 0 to X*Y -1
  3. Set the first row and first column indices to have value 1

Here is the code for my program (numWaysXY_iterative.cc)

#include<stdio.h>
#include<iostream>

using namespace std;

void printMap(int X, int Y, long long int **map)
{
    printf("printing map(%d, %d)...\n\n", X, Y);
    for(long long int i = 0; i < Y; i++)
    {
        for(long long int j = 0; j < X; j++)
        {
            printf("(%lld, %lld) value: %lld\t", j, i, map[j][i]);
        }
        printf("\n");
    }
    printf("Finished Printing map\n");
}

long long int numWaysXY_iterative(long long int X, long long int Y)
{
    long long int **map = new long long int*[X];

    long long int value = 0;

    for(long long int i = 0; i < X; i++)
    {
        map[i] = new long long int(Y);
        for(long long int j = 0; j < Y; j++)
        {
            printf("i: %lld, j: %lld, value: %lld\n", i, j, value);
            map[i][j] = value;
            value++;
        }
    }

    //debugging - print map
    printMap(X,Y, map);

    //initialize first row and first column entries to 1
    for(long long int i = 0; i < X; i++)
    {
        map[i][0] = 1;
    }
    for(long long int j = 0; j < Y; j++)
    {
        map[0][j] = 1;
    }

    //debugging - print map
    printMap(X,Y, map);

    /*
    for(int i = 0; i < X, i++)
    {
        for(int j = 0; j > Y, j++)
        {
            if
        }
    }
    */
    return map[X-1][Y-1];
}

int main()
{
    (void) numWaysXY_iterative(5,3);
}

Afer compiling and running the code, I get this output

$ g++ my_solution/numWaysXY_iterative/numWaysXY_iterative.cc -m64 -o executables/numWaysXY_iterative 
$ 
$ 
$ 
$ ./executables/numWaysXY_iterative 
i: 0, j: 0, value: 0
i: 0, j: 1, value: 1
i: 0, j: 2, value: 2
i: 1, j: 0, value: 3
i: 1, j: 1, value: 4
i: 1, j: 2, value: 5
i: 2, j: 0, value: 6
i: 2, j: 1, value: 7
i: 2, j: 2, value: 8
i: 3, j: 0, value: 9
i: 3, j: 1, value: 10
i: 3, j: 2, value: 11
i: 4, j: 0, value: 12
i: 4, j: 1, value: 13
i: 4, j: 2, value: 14
printing map(5, 3)...

(0, 0) value: 0 (1, 0) value: 3 (2, 0) value: 6 (3, 0) value: 9 (4, 0) value: 12    
(0, 1) value: 1 (1, 1) value: 4 (2, 1) value: 7 (3, 1) value: 10    (4, 1) value: 13    
(0, 2) value: 3 (1, 2) value: 6 (2, 2) value: 9 (3, 2) value: 12    (4, 2) value: 14    
Finished Printing map
printing map(5, 3)...

(0, 0) value: 1 (1, 0) value: 1 (2, 0) value: 1 (3, 0) value: 1 (4, 0) value: 1 
(0, 1) value: 1 (1, 1) value: 4 (2, 1) value: 7 (3, 1) value: 10    (4, 1) value:    13 
(0, 2) value: 1 (1, 2) value: 1 (2, 2) value: 1 (3, 2) value: 1 (4, 2) value: 14    
Finished Printing map

Problems:
1. After initializing the values of the array in lines 26 - 35, even though the value
   variable is strictly increasing, and each array indice is supposedly getting a unique
   value assigned to it, this is not being reflected in the array. You can see that
   map[0][2] == map[1][0] for example.

2. I'm setting the first row and first column array elements to have the value 1 in lines
   40 - 48, but again this is not reflected when the array is printed out. Instead it
   seems that the first row, first column, and all elements in the last row besides the
   last are being set to 1.

After going over my logic several times and not seeing anything wrong, I decided to make another version of the program, just replacing the "long long int" variables with int instead.

This code is pasted below (debug_numWaysXY_iterative.cc)

 #include<stdio.h>
 #include<iostream>

 using namespace std;

 void printMap(int X, int Y,  int **map)
 {
     printf("printing map(%d, %d)...\n\n", X, Y);
     for(int i = 0; i < Y; i++)
     {
         for(int j = 0; j < X; j++)
         {
            printf("(%d, %d) value: %d\t", j, i, map[j][i]);
         }
         printf("\n");
     }
     printf("Finished Printing map\n");
 }

  int numWaysXY_iterative(int X, int Y)
 {
      int **map = new  int*[X];

      int value = 0;

     for(int i = 0; i < X; i++)
     {
         map[i] = new  int(Y);
         for(int j = 0; j < Y; j++)
         {
             printf("i: %d, j: %d, value: %d\n", i, j, value);
             map[i][j] = value;
             value++;
         }
     }

     //debugging - print map
     printMap(X,Y, map);

     //initialize first row and first column entries to 1
     for(int i = 0; i < X; i++)
     {
         map[i][0] = 1;
     }
     for(int j = 0; j < Y; j++)
     {
         map[0][j] = 1;
     }

     //debugging - print map
     printMap(X,Y, map);

     /*
     for(int i = 0; i < X, i++)
     {
         for(int j = 0; j > Y, j++)
         {
             if
         }
     }
     */
     return map[X-1][Y-1];
 }

 int main()
 {
     (void) numWaysXY_iterative(5,3);
 }

Just to prove that the only difference I made between these 2 programs is replacing the "long long int" variables with "int" (and changing the printf calls accordingly), here is the diff between the 2 source files

$ diff my_solution/numWaysXY_iterative/numWaysXY_iterative.cc my_solution/numWaysXY_iterative/debug_numWaysXY_iterative.cc 
6c6
< void printMap(int X, int Y, long long int **map)
---
> void printMap(int X, int Y,  int **map)
9c9
<     for(long long int i = 0; i < Y; i++)
---
>     for(int i = 0; i < Y; i++)
11c11
<         for(long long int j = 0; j < X; j++)
---
>         for(int j = 0; j < X; j++)
13c13
<            printf("(%lld, %lld) value: %lld\t", j, i, map[j][i]);
---
>            printf("(%d, %d) value: %d\t", j, i, map[j][i]);
20c20
< long long int numWaysXY_iterative(long long int X, long long int Y)
---
>  int numWaysXY_iterative(int X, int Y)
22c22
<     long long int **map = new long long int*[X];
---
>      int **map = new  int*[X];
24c24
<     long long int value = 0;
---
>      int value = 0;
26c26
<     for(long long int i = 0; i < X; i++)
---
>     for(int i = 0; i < X; i++)
28,29c28,29
<         map[i] = new long long int(Y);
<         for(long long int j = 0; j < Y; j++)
---
>         map[i] = new  int(Y);
>         for(int j = 0; j < Y; j++)
31c31
<             printf("i: %lld, j: %lld, value: %lld\n", i, j, value);
---
>             printf("i: %d, j: %d, value: %d\n", i, j, value);
41c41
<     for(long long int i = 0; i < X; i++)
---
>     for(int i = 0; i < X; i++)
45c45
<     for(long long int j = 0; j < Y; j++)
---
>     for(int j = 0; j < Y; j++)
$

However when this version of the code runs, I get output that I expect!!

$ g++ my_solution/numWaysXY_iterative/debug_numWaysXY_iterative.cc -m64 -o executables/debug_numWaysXY_iterative 
$ 
$ 
$ 
$ ./executables/debug_numWaysXY_iterative 
i: 0, j: 0, value: 0
i: 0, j: 1, value: 1
i: 0, j: 2, value: 2
i: 1, j: 0, value: 3
i: 1, j: 1, value: 4
i: 1, j: 2, value: 5
i: 2, j: 0, value: 6
i: 2, j: 1, value: 7
i: 2, j: 2, value: 8
i: 3, j: 0, value: 9
i: 3, j: 1, value: 10
i: 3, j: 2, value: 11
i: 4, j: 0, value: 12
i: 4, j: 1, value: 13
i: 4, j: 2, value: 14
printing map(5, 3)...

(0, 0) value: 0 (1, 0) value: 3 (2, 0) value: 6 (3, 0) value: 9 (4, 0) value: 12    
(0, 1) value: 1 (1, 1) value: 4 (2, 1) value: 7 (3, 1) value: 10    (4, 1) value: 13    
(0, 2) value: 2 (1, 2) value: 5 (2, 2) value: 8 (3, 2) value: 11    (4, 2) value: 14    
Finished Printing map
printing map(5, 3)...

(0, 0) value: 1 (1, 0) value: 1 (2, 0) value: 1 (3, 0) value: 1 (4, 0) value: 1 
(0, 1) value: 1 (1, 1) value: 4 (2, 1) value: 7 (3, 1) value: 10    (4, 1) value: 13    
(0, 2) value: 1 (1, 2) value: 5 (2, 2) value: 8 (3, 2) value: 11    (4, 2) value: 14    
Finished Printing map
$

As I've shown I compiled both programs with -m64 flag, and I have a i7 processor in my laptop, which is a 64 bit processor. I've also tried versions of my program with all instances of "long long int" replaced with "long int" and another version where I've replaced all "long long int" with "int64_t", and I'm getting incorrect output for both of those versions too.

Anyone have any idea why I'm seeing a difference in behavior here?

  • 1
    Please do not number lines, it makes copy-pasting code difficult. – Pascal Cuoq Jun 09 '14 at 09:10
  • I had the line numbers there as a reference to the diff. I've removed them. Would you please undo your negative rating so that others don't think this is a stupid question and ignore it. I'm interested in knowing why the behavior is different. – user3721655 Jun 09 '14 at 09:45
  • Did you mean to write `new long long int[Y]` instead of `new long long int(Y)`? This seems to be simple array bounds error. – Dietmar Kühl Jun 09 '14 at 10:02
  • Yes Dietmar!! That did it, thanks a lot! What a stupid mistake. Strange thing is though that I have the same mistake in the version with int instead of long long int, and that one works. Is this because ints and pointers to ints are the same size, where as long long ints are not the same size and pointers to long long ints? Thanks again! – user3721655 Jun 09 '14 at 22:54

0 Answers0