-1

I'm writing a program for my algorithmic math class at university and I'm using Win 7 (x64), Eclipse Oxygen.1a Release (4.7.1a) with MinGW 6.3.0.

Whenever I build and run the program it crashes with windows claiming 'Abgabe3.exe stopped working' but when trying to find the problem using the debugger and breakpoints I step trough the whole program and it finishes without errors...

I stripped everything not used by the problematic function and copied everything into a seperate file and the exact problem occurs. Maybe somebody has a clue what happened at my side. ^^

#include <math.h>       /* pow, sqrt */
#include <iostream>     /* cin, cout */
#include <new>          /* new */
#include <string>       /* string */
#include <stdlib.h>     /* srand, rand */
#include <time.h>       /* time */

using namespace std;


void NORM(double* res, double* x, int n){
    res[0] = 0.0;
    for(int i = 0; i < n; i++){
        res[0] += pow(x[i], 2);
    }
    res[0] = sqrt(res[0]);
}

void initRand(double* x, int n){
    srand (time(NULL) * rand());
    for(int i = 0; i < n; i++){
        x[i] = (((double) rand()) / ((double) RAND_MAX));
    }
}

void createArray(double* &x, int n){
    if (n > 0){
        x = new double[n];
        initRand(x, n);
    }
}

void printArray(double* x, int n){
    if (x != NULL){
    cout<<"(\n";
    for(int i = 0; i < n; i++){
        if(i+1 == n) cout<<x[i];
        else if ((i % 5) == 0) cout<<x[i];
        else if ( ((i+1) % 5) == 0 ){
            cout<<", "<<x[i]<<"\n";
        }
        else {
            cout<<", "<<x[i];
        }
    }
    cout<<"\n)\n";
    }
    else cout<<"\nError: pointer = NULL\n";
}

unsigned long long int bin(unsigned int n, unsigned int k){
    unsigned long long res = 1;
    if(k == 0) return 1;
    else if( n >= k){
        for(unsigned long long int i = 1; i <= k; i++){
            res *= (n + 1 - i) / i;
        }
    }
    else return 0;
    return res;
}

void newArray(double** x, unsigned int v, unsigned int n){
    for(unsigned int i = 0; i < v; i++){
        double* ptr = x[i];
        createArray(ptr,n);
        x[i] = ptr;
    }
}

void experiment(double** vektorArray){
    unsigned int n = 10, v = 20;
    cout<<"Dimension n = "<<n<<"\nAnzahl Versuche v = "<<v<<endl;
    //Erstellen der Vektoren
    cout<<"Erstellen - starte\n";

    vektorArray = new double*[n];
    newArray(vektorArray, v, n);

    cout<<"Erstellen - fertig\n";

    for(unsigned int i = 0; i < v; i++){
        if(i%10 == 0) printArray(vektorArray[i], n);
    }
}
int main(int argc, char** argv){
    double** vektorArray = NULL;
    experiment(vektorArray);
    return 0;
}
Cœur
  • 37,241
  • 25
  • 195
  • 267
Tignite
  • 87
  • 7
  • Unrelated: Seeding the random number generator with a random number before the random number generator is seeded is a bit weird. I don't think `srand (time(NULL) * rand());` will do much for you that use of the `` library wouldn't do better. – user4581301 Nov 15 '17 at 18:45
  • Unrelated: `pow` is designed to compute crazy stuff like e to the power of pi. Using it to square is vast overkill. You are almost always better off with `x*x` – user4581301 Nov 15 '17 at 18:56
  • I ran into the problem when seeding with time(NULL) only the vectors would all be generated equally and thats why I came up with this weird sran.. ^^ Okay, I won't use pow any more to calculate squares! :D – Tignite Nov 16 '17 at 04:58
  • `time(NULL)` returns the current number in seconds. This means if you call `srand` more often than once a second you will reseed the generator with the same seed and generate the same sequence. Typical usage of `srand` is to call it once near the beginning of the `main` function and then leave it alone because you almost never need to reseed the generator. If you find yourself in a case where you do need to reseed the generator, you're probably better off using a more advanced generator. – user4581301 Nov 16 '17 at 05:11
  • Since we are instructed to use rand and srand your suggestion of moving the srand into the main function should do the trick for me then. Thank you very much – Tignite Nov 16 '17 at 09:33

1 Answers1

2
vektorArray = new double*[n];

created an array of size n, but

void newArray(double** x, unsigned int v, unsigned int n)
{
    for (unsigned int i = 0; i < v; i++)
    {
        double* ptr = x[i];
        createArray(ptr, n);
        x[i] = ptr;
    }
}

and

for (unsigned int i = 0; i < v; i++)
{
    if (i % 10 == 0)
        printArray(vektorArray[i], n);
}

index that array with v. Looks like you got your variables crossed. Strongly recommend giving variables better, more descriptive names to help make this more obvious.

user4581301
  • 33,082
  • 7
  • 33
  • 54
  • Besides being non desciptive they are right. I need a n-dimensional vector and v (for the german word "versuche" = trials) as a counter for vectors. The array itself is created at 'createArray(ptr, n);' and printed at 'printArray(vektorArray[i], n);' So variables shouldn't be a problem.. – Tignite Nov 16 '17 at 04:54
  • @Tignite They may be right, but your usage is wrong. `vektorArray` is allocated 10 slots. `for (unsigned int i = 0; i < v; i++)` coupled with `vektorArray[i]` accesses 20 slots, running outside the bounds of the array's allocated memory and into the wild world of undefined behaviour. That means the program can do whatever it wants, including look like it works sometimes. – user4581301 Nov 16 '17 at 05:14
  • I totally overlooked your first quote and didn't notice the 'new double[n]'! I will correct and try it once I'm back home but I still don't understand why this won't cause an error when stepping through inside debug mode.. – Tignite Nov 16 '17 at 09:30
  • Because of dumb bad luck. More here: https://stackoverflow.com/questions/1239938/accessing-an-array-out-of-bounds-gives-no-error-why – user4581301 Nov 16 '17 at 15:46
  • All right then, thank you again! That little sneaky n made the code work! – Tignite Nov 19 '17 at 16:16