1

So I've been working on problem 15 from the Project Euler's website , and my solution was working great up until I decided to remove the cout statements I was using for debugging while writing the code. My solution works by generating Pascal's Triangle in a 1D array and finding the element that corresponds to the number of paths in the NxN lattice specified by the user. Here is my program:

#include <iostream>
using namespace std;

//Returns sum of first n natural numbers
int sumOfNaturals(const int n)
{
    int sum = 0;
    for (int i = 0; i <= n; i++)
    {
        sum += i;
    }
    return sum;
}

void latticePascal(const int x, const int y, int &size)
{
    int numRows = 0;
    int sum = sumOfNaturals(x + y + 1);
    numRows = x + y + 1;

    //Create array of size (sum of first x + y + 1 natural numbers) to hold all elements in P's T
    unsigned long long *pascalsTriangle = new unsigned long long[sum];
    size = sum;

    //Initialize all elements to 0
    for (int i = 0; i < sum; i++)
    {
        pascalsTriangle[i] = 0;
    }
    //Initialize top of P's T to 1
    pascalsTriangle[0] = 1;
    cout << "row 1:\n" << "pascalsTriangle[0] = " << 1 << "\n\n";  // <--------------------------------------------------------------------------------

    //Iterate once for each row of P's T that is going to be generated
    for (int i = 1; i <= numRows; i++)
    {
        int counter = 0;
        //Initialize end of current row of P's T to 1
        pascalsTriangle[sumOfNaturals(i + 1) - 1] = 1;
        cout << "row " << i + 1 << endl;   // <--------------------------------------------------------------------------------------------------------

        //Iterate once for each element of current row of P's T
        for (int j = sumOfNaturals(i); j < sumOfNaturals(i + 1); j++)
        {
            //Current element of P's T is not one of the row's ending 1s
            if (j != sumOfNaturals(i) && j != (sumOfNaturals(i + 1)) - 1)
            {
                pascalsTriangle[j] = pascalsTriangle[sumOfNaturals(i - 1) + counter] + pascalsTriangle[sumOfNaturals(i - 1) + counter + 1];
                cout << "pascalsTriangle[" << j << "] = " << pascalsTriangle[j] << '\n';   // <--------------------------------------------------------
                counter++;
            }
            //Current element of P's T is one of the row's ending 1s
            else
            {
                pascalsTriangle[j] = 1;
                cout << "pascalsTriangle[" << j << "] = " << pascalsTriangle[j] << '\n';  // <---------------------------------------------------------
            }
        }
        cout << endl;
    }

    cout << "Number of SE paths in a " << x << "x" << y << " lattice: " << pascalsTriangle[sumOfNaturals(x + y) + (((sumOfNaturals(x + y + 1) - 1) - sumOfNaturals(x + y)) / 2)] << endl;
    delete[] pascalsTriangle;
    return;
}

int main()
{
    int size = 0, dim1 = 0, dim2 = 0;

    cout << "Enter dimension 1 for lattice grid: ";
    cin >> dim1;
    cout << "Enter dimension 2 for lattice grid: ";
    cin >> dim2;
    latticePascal(dim1, dim2, size);

    return 0;
}

The cout statements that seem to be saving my program are marked with commented arrows. It seems to work as long as any of these lines are included. If all of these statements are removed, then the program will print: "Number of SE paths in a " and then hang for a couple of seconds before terminating without printing the answer. I want this program to be as clean as possible and to simply output the answer without having to print the entire contents of the triangle, so it is not working as intended in its current state.

OrenIshShalom
  • 5,974
  • 9
  • 37
  • 87
philly b
  • 21
  • 3
  • 1
    Try to turn on all warnings and sanitize all undefined behaviors... – user202729 Aug 04 '18 at 03:17
  • My compiler doesn't seem to be giving me any warnings, I'm using visual studio community 2017. And I'm not sure where undefined behavior might be occurring... – philly b Aug 04 '18 at 03:23
  • Check out [Tool to debug buffer overflows in C++ program with Visual Studio? - Stack Overflow](https://stackoverflow.com/questions/32240453/tool-to-debug-buffer-overflows-in-c-program-with-visual-studio)! – user202729 Aug 04 '18 at 03:25
  • I'll take a look! Thanks for the link. – philly b Aug 04 '18 at 03:28

2 Answers2

1

There's a good chance that either the expression to calculate the array index or the one to calculate the array size for allocation causes undefined behaviour, for example, a stack overflow.

Because the visibility of this undefined behaviour to you is not defined the program can work as you intended or it can do something else - which could explain why it works with one compiler but not another.

You could use a vector with vector::resize() and vector::at() instead of an array with new and [] to get some improved information in the case that the program aborts before writing or flushing all of its output due to an invalid memory access.

If the problem is due to an invalid index being used then vector::at() will raise an exception which you won't catch and many debuggers will stop when they find this pair of factors together and they'll help you to inspect the point in the program where the problem occurred and key facts like which index you were trying to access and the contents of the variables.

They'll typically show you more "stack frames" than you expect but some are internal details of how the system manages uncaught exceptions and you should expect that the debugger helps you to find the stack frame relevant to your problem evolving so you can inspect the context of that one.

codeshot
  • 1,183
  • 1
  • 9
  • 20
0

Your program works well with g++ on Linux:

$ g++ -o main pascal.cpp
$ ./main
Enter dimension 1 for lattice grid: 3
Enter dimension 2 for lattice grid: 4








Number of SE paths in a 3x4 lattice: 35

There's got to be something else since your cout statements have no side effects. Here's an idea on how to debug this: open 2 visual studio instances, one will have the version without the cout statements, and the other one will have the version with them. Simply do a step by step debug to find the first difference between them. My guess is that you will realize that the cout statements have nothing to do with the error.

OrenIshShalom
  • 5,974
  • 9
  • 37
  • 87
  • Huh. That's odd... I will take your advice and do just that though! Thanks for the response. Guess my first move next time I encounter a bug like this will be to just try it out with a different compiler.. – philly b Aug 04 '18 at 04:30