# Thread: Help with pointers

1. ## Help with pointers

Why does the address &ra[0] keep changing?

Code:
```void overlappingPermutations(Distribution& D, int* ra) {

// overlappingPermutations
//
//      Take five consecutively-generated RNs at a time and
//      determine their order. There are 5P5 = 120 different
//      orderings.
//
//
// Example:
//
//
//
//
// Expected distribution: Flat
//
// Complexity: O(N)
vector<int> pattern(120);
int is[5] = {0};

while(ra) {
int i = 0;
while(i < 5){
is[i++] = *ra++;
}
if(ra - &ra[0] == 0) cout << "bang!\n"; // Always written!
rankPermutations(pattern, is, 5);
}

// Rest of implementation comes later

}

// ...

int main(void) {

Distribution* D = new Distribution[12];
bool running = true;
int* ra;

try {

ra = new int[10000000];

} catch (bad_alloc) {

cout << "Memory allocation failed\n";
return 127;

}

long int count = 0;

seedRNG();

while(running) {

ra[count++] = rand();

if(count % 1000000 == 0) cout << count << " values so far.\n";
if(count == 10000000) running = false;
}

diehard(ra); // Diehard just calls functions like `overlappingPermutations',
// which all have the same prototype.
}```
Thanks.

2. ra and &ra[0] should always be equal. ra is not a magic array whose start won't change and a magic pointer that you can make point elsewhere at the same time.

3. I suggest that you post the smallest and simplest compilable program that demonstrates the problem.

I noticed a few problems:

1. You use new[] in main(), but it lacks a matching delete[].

2. You rather randomly return 127 from main(). You should return 0, EXIT_SUCCESS or perhaps in this case, EXIT_FAILURE. The latter two are found in <cstddef>.

3. You might want to indent by 4 spaces instead. 2 spaces (or at one point, it was one space) can be rather... insignificant.

Also, I noticed that:
Code:
```while(running) {

ra[count++] = rand();

if(count &#37; 1000000 == 0) cout << count << " values so far.\n";
if(count == 10000000) running = false;
}```
Is far more simply and directly expressed as:
Code:
```while (count < 10000000) {
ra[count++] = rand();

if(count % 1000000 == 0) cout << count << " values so far.\n";
}```

4. ra and &ra[0] should always be equal. ra is not a magic array whose start won't change and a magic pointer that you can make point elsewhere at the same time.
But doesn't ra++ move the pointer up by sizeof(int)? I thought &ra[0] points to the zeroth element (always), and ra is the current position. Does ra++ move &ra[0] up too? Why?

5. ra[0] points to the zeroth element of the array starting at ra.
ra++ does increment the pointer - and ra[0] points the zero'th element starting at ra.

ra is just a pointer sized variable. The compiler does not generate code to keep track of ra's initial value - as the "fixed zero'th element".

gg

6. ra is a pointer, which (in this context) should be equivalent to &ra[0], no matter what you've done to ra previously. Which means that ra-&ra[0] should always compare equal to zero.

If you do this;
Code:
```    int *rb = new int[5];
int *ra = rb;
++ra;```
then ra will be equal to rb+1. Manipulating ra[0] (or, equivalently, *ra) will therefore manipulate rb[1]. So &ra[0] == &rb[1] will always compare true.

7. Thanks for your help!

I traced the problem to the way values are assigned to an array in a structure:

Code:
```#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
#include <ctime>
#include <cstddef>

using namespace std;

typedef struct {

string d;   // Statistical distribution

int n;      // Number of entries

double* dx; // x-values
double* dy; // y-values
double* dz; // z-values

} Distribution;

void seedRNG() {

srand(static_cast<unsigned>(time(0)));

}

void fill(Distribution& D, double x) {

*(D.dx + D.n) = x; // crash!!!!!

D.n++;
}

double l2Norm(double p1, double p2) {

return p1 - p2 >= 0 ? p1 - p2 : p2 - p1;

}

void poissonL2Norm(Distribution& D, int* ra) {

// poissonL2Norm
//
//      Throw beans on a closed interval of width RAND_MAX+1
//      and measure the distance between adjacent beans:
//
// Example:
//           0                       RAND_MAX
//           [--B---BB--- ... ---B--B]
//              |< >||<         >|<>|
//
//    Width:    3   1  RAND_MAX-7 2
//
// Expected distribution: Poisson
//
// Efficiency: O(n)

//    while(*(1+ra++));
fill(D, l2Norm(*ra, *(ra+1)) );

}

void diehard(int* ra, Distribution* D  =0) {

poissonL2Norm(D[0], ra);

}

int main(void) { // Thanks, laserlight

Distribution* D = new Distribution[12];
int* ra;

try {
ra = new int[10000000];

} catch (bad_alloc) { // Handling not mandatory, but safe
cout << "Memory exhausted\n";
return EXIT_FAILURE;
}

long int count = 0;

seedRNG();

cout << "start: " << ra << '\n';
while(count < 10000000) {

ra[count++] = rand();
if(count % 1000000 == 0) cout << count << " values so far.\n";
}

diehard(ra, D);

delete[] ra;
delete[] D;

}```
This program goes up in flames at runtime because of the way I "fill" the distribution. I just want to add one number at a time to D.dx, but I'm having trouble doing this. Any ideas? This is my first 1000-liner in C++, and it looks like I'll be 100 by the time it works completely : (

Also: Emacs' syntax highlighter for C++ is only indenting two deep. How do you tell it to go four deep? I'm so, so lost here : (

8. You are incorrectly assuming, when you create a pointer, that it points at something valid.

For example;
Code:
```int main()
{
int *p;
*(p + 4) = 5;   // undefined behaviour here
}```
yields undefined behaviour, for which a common (but not guaranteed) symptom is a program crash, as p is uninitialised. It does NOT point at the first element of any array.

Furthermore, initialising to NULL (or zero), also yield undefined behaviour.
Code:
```#include <stdlib.h>
int main()
{
int *p = NULL;
*(p + 4) = 5;   // undefined behaviour
}```
The bottom line is that YOU need to ensure the pointer points at something valid.
Code:
```int main()
{
int *p = new int[5];
*(p + 4) = 5;    //  OK, as p points at an array of 5 elements
delete [] p;
*(p + 4) = 10;   // undefined behaviour here, as the memory pointed at by p has been released by the program
}```

9. It does NOT point at the first element of any array.
...
The bottom line is that YOU need to ensure the pointer points at something valid.
Thanks!

Popular pages Recent additions