# Help with pointers

• 12-26-2007
slippy
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.
• 12-26-2007
anon
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.
• 12-26-2007
laserlight
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"; }```
• 12-26-2007
slippy
Quote:

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?
• 12-26-2007
Codeplug
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
• 12-26-2007
grumpy
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.
• 12-26-2007
slippy

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 : (
• 12-27-2007
grumpy
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 }```
• 12-27-2007
slippy
Quote:

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!