Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Pointer Pointing to Itself?

Pointer Pointing to Itself?

Scheduled Pinned Locked Moved C / C++ / MFC
visual-studiodata-structuresquestiondiscussion
5 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Skippums
    wrote on last edited by
    #1

    I have a class that acts something like the following:

    class Foo {
    private:
    int const (&InitPrimes() const)[3] {
    int (*const rval)[3] = new int[1][3];
    (*rval)[0] = 2;
    (*rval)[1] = 3;
    (*rval)[2] = 5;
    return *rval;
    }

    public:
    int const (&primes)[3];

    explicit Foo() : primes(InitPrimes()) { }
    virtual ~Foo() { delete\[\] ℙ }
    

    };

    If I have the following code in a main function, all three of the cout statements print the same value:

    Foo a;
    cout << a.primes << endl;
    cout << &a.primes[0] << endl;
    cout << &a.primes << endl;

    How is this possible? It seems logical that "a.primes" == "&a.primes[0]", but shouldn't "&a.primes" be a distinct value? If they are the same, then shouldn't the following contradiction be true (assume all three return value 0xF0):

    Address 0xF0 (&a.primes ) is of type "(int*)[3]" and holds the value 0xF0, the location of a.primes
    Address 0xF0 ( a.primes ) is of type " int [3]" and holds the value 0xF0, the address of the first element in the array
    Address 0xF0 ( a.primes[0]) is of type " int " and holds the value 2, the first prime number

    Clearly I am misinterpreting which of these assumptions is false, because I know that address 0xF0 can't be 0xF0 and 2 at the same time (let's not get into a discussion on simultaneity with respect to relativity). If I type

    *((int*)0xF0)

    into the immediate window (VS 2008), it returns 2, but then why is &a.primes == 0xF0? Any clarification on why the above is happening would be greatly appreciated. Thanks,

    Sounds like somebody's got a case of the Mondays -Jeff

    P A 2 Replies Last reply
    0
    • S Skippums

      I have a class that acts something like the following:

      class Foo {
      private:
      int const (&InitPrimes() const)[3] {
      int (*const rval)[3] = new int[1][3];
      (*rval)[0] = 2;
      (*rval)[1] = 3;
      (*rval)[2] = 5;
      return *rval;
      }

      public:
      int const (&primes)[3];

      explicit Foo() : primes(InitPrimes()) { }
      virtual ~Foo() { delete\[\] &primes; }
      

      };

      If I have the following code in a main function, all three of the cout statements print the same value:

      Foo a;
      cout << a.primes << endl;
      cout << &a.primes[0] << endl;
      cout << &a.primes << endl;

      How is this possible? It seems logical that "a.primes" == "&a.primes[0]", but shouldn't "&a.primes" be a distinct value? If they are the same, then shouldn't the following contradiction be true (assume all three return value 0xF0):

      Address 0xF0 (&a.primes ) is of type "(int*)[3]" and holds the value 0xF0, the location of a.primes
      Address 0xF0 ( a.primes ) is of type " int [3]" and holds the value 0xF0, the address of the first element in the array
      Address 0xF0 ( a.primes[0]) is of type " int " and holds the value 2, the first prime number

      Clearly I am misinterpreting which of these assumptions is false, because I know that address 0xF0 can't be 0xF0 and 2 at the same time (let's not get into a discussion on simultaneity with respect to relativity). If I type

      *((int*)0xF0)

      into the immediate window (VS 2008), it returns 2, but then why is &a.primes == 0xF0? Any clarification on why the above is happening would be greatly appreciated. Thanks,

      Sounds like somebody's got a case of the Mondays -Jeff

      P Offline
      P Offline
      Peter_in_2780
      wrote on last edited by
      #2

      IIRC, the original C idea (almost 40 years ago) was that the "value" of an array symbol was its base address. In other words, array == &array == &(array[0]). This dates from the days when a pointer was a pointer (to anything), and void was not yet a keyword. Somewhere in a standard or pseudo-standard that I can't find right now, there is a statement to the effect that the address-of operator (&) is optional when referring to an array. I remember some fairly energetic debate when I was working on a very early non-PDP11 implementation of Unix and C. [OT, sort of] I think this is sufficiently removed from the present message in the time dimension for considerations of simultaneity to be of probability zero. ;P ] Cheers from an old-timer, Peter

      Software rusts. Simon Stephenson, ca 1994.

      1 Reply Last reply
      0
      • S Skippums

        I have a class that acts something like the following:

        class Foo {
        private:
        int const (&InitPrimes() const)[3] {
        int (*const rval)[3] = new int[1][3];
        (*rval)[0] = 2;
        (*rval)[1] = 3;
        (*rval)[2] = 5;
        return *rval;
        }

        public:
        int const (&primes)[3];

        explicit Foo() : primes(InitPrimes()) { }
        virtual ~Foo() { delete\[\] &primes; }
        

        };

        If I have the following code in a main function, all three of the cout statements print the same value:

        Foo a;
        cout << a.primes << endl;
        cout << &a.primes[0] << endl;
        cout << &a.primes << endl;

        How is this possible? It seems logical that "a.primes" == "&a.primes[0]", but shouldn't "&a.primes" be a distinct value? If they are the same, then shouldn't the following contradiction be true (assume all three return value 0xF0):

        Address 0xF0 (&a.primes ) is of type "(int*)[3]" and holds the value 0xF0, the location of a.primes
        Address 0xF0 ( a.primes ) is of type " int [3]" and holds the value 0xF0, the address of the first element in the array
        Address 0xF0 ( a.primes[0]) is of type " int " and holds the value 2, the first prime number

        Clearly I am misinterpreting which of these assumptions is false, because I know that address 0xF0 can't be 0xF0 and 2 at the same time (let's not get into a discussion on simultaneity with respect to relativity). If I type

        *((int*)0xF0)

        into the immediate window (VS 2008), it returns 2, but then why is &a.primes == 0xF0? Any clarification on why the above is happening would be greatly appreciated. Thanks,

        Sounds like somebody's got a case of the Mondays -Jeff

        A Offline
        A Offline
        Aescleal
        wrote on last edited by
        #3

        Your problem is that you say that &a.primes is of type (int *)[3]. (Actually I think you mean int (*)[3] - a pointer to an array of three ints, not an array to three pointers to int, but that's another story) It's not - it's type is int * const. The name of an array is an alias for the address of the first element in that array. This means that:

        T t[ N ];

        t == &t[ 0 ];

        for all T and N. Likewise the address of an array is an alias for the first element in that array. Again this means that:

        T t[ N ];

        &t == &t[ 0 ];

        for all T and N. it also means that the type of &t is T * const, not (T *)[3]; as you asserted in your post. So t, &t and &t[ 0 ] are synonyms for the same thing and *t, *&t and t[ 0 ] all refer to the same location in memory. Cheers, Ash

        S 1 Reply Last reply
        0
        • A Aescleal

          Your problem is that you say that &a.primes is of type (int *)[3]. (Actually I think you mean int (*)[3] - a pointer to an array of three ints, not an array to three pointers to int, but that's another story) It's not - it's type is int * const. The name of an array is an alias for the address of the first element in that array. This means that:

          T t[ N ];

          t == &t[ 0 ];

          for all T and N. Likewise the address of an array is an alias for the first element in that array. Again this means that:

          T t[ N ];

          &t == &t[ 0 ];

          for all T and N. it also means that the type of &t is T * const, not (T *)[3]; as you asserted in your post. So t, &t and &t[ 0 ] are synonyms for the same thing and *t, *&t and t[ 0 ] all refer to the same location in memory. Cheers, Ash

          S Offline
          S Offline
          Skippums
          wrote on last edited by
          #4

          Alright, I think that I understand what you are saying (although I'm still confused as to why the designers of C decided to do this). The point of my post was to ensure that class Foo is correctly deallocating the member primes in it's destructor. If I understand you correctly, then all of the following should be equivalent statements, all of which result in no memory leaks:

          virtual ~Foo() {
          // Select exactly one of the following
          delete[] primes;
          delete[] ℙ
          delete[] &primes[0];
          }

          Is it true that all of these correctly deallocate primes in the example? Thanks,

          Sounds like somebody's got a case of the Mondays -Jeff

          A 1 Reply Last reply
          0
          • S Skippums

            Alright, I think that I understand what you are saying (although I'm still confused as to why the designers of C decided to do this). The point of my post was to ensure that class Foo is correctly deallocating the member primes in it's destructor. If I understand you correctly, then all of the following should be equivalent statements, all of which result in no memory leaks:

            virtual ~Foo() {
            // Select exactly one of the following
            delete[] primes;
            delete[] ℙ
            delete[] &primes[0];
            }

            Is it true that all of these correctly deallocate primes in the example? Thanks,

            Sounds like somebody's got a case of the Mondays -Jeff

            A Offline
            A Offline
            Aescleal
            wrote on last edited by
            #5

            The best way of avoiding delete stress like this is to not bother with fiddling about with multi-dimensional arrays. Use a vector or vector of vectors and you don't have to worry about declaring it properly, sizing it or freeing it. The class does all that for you with very little overhead (bit of space, maybe some run-time cost if your optimiser isn't up to much). Or another way is to handle the multidimensional bit yourself over a one dimensional array but that's a bit fiddlier and not the sort of thing you want to think about unless you're writing a collection class. Cheers, Ash PS: All those will delete primes - just be careful of what they're pointing to. Arrays of pointers are a good way of going gaga and there's usually a better way of doing them. PPS: The designers of C designed pointers and arrays to be very close to the hardware - which is why they're a bugger to use properly. Fortunately in C++ you don't need to use them that much, there's almost always a better alternative.

            1 Reply Last reply
            0
            Reply
            • Reply as topic
            Log in to reply
            • Oldest to Newest
            • Newest to Oldest
            • Most Votes


            • Login

            • Don't have an account? Register

            • Login or register to search.
            • First post
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • World
            • Users
            • Groups