casting - pointer to pointer

This is a discussion on casting - pointer to pointer within the C Programming forums, part of the General Programming Boards category; If you fully understand pointers, understanding pointers-to-pointers should be no problem. Pointers only hold an address to something else, think ...

  1. #16
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    If you fully understand pointers, understanding pointers-to-pointers should be no problem.

    Pointers only hold an address to something else, think of it like man pointing to something. Consider the following, let man = pointer.

    Code:
    [man 0] -> [man 1] -> [man 2] -> [the man you want]
    You want to remember where [the man you want] is,
    * so you tell man 2 to remember where he is,
    * you tell man 1 to remember where man 2 is
    * you tell man 0 to remember where man 1 is

    If you want to find [the man you want] you can either,
    1. ask man 0 where man 1 is (see 2.)
    2. ask man 1 where man 2 is (see 3.)
    3. ask man 2 where [the man you want] is.

    You can of course skip to 2 or 3 or even straight to the man.

    I hope my corny example made it clear

  2. #17
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    23,031
    Quote Originally Posted by terminator View Post
    there is only little explanation about pointer to pointer...
    Is there any good book or website with examples?
    It's simple. If you need to modify a pointer (a variable of type type*) in another function then you must pass the variable by pointer, so if the type is type* (pointer), then the new type you would need the function to take is type** (a pointer to type type*).
    For example if you wish to allocate memory via malloc into a variable stored in main (a normal variable can't hold an address, so you need to pass a pointer!).
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  3. #18
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Pointer to pointer is nothing "special". All pointer variables hold the address of something else. A pointer to pointer is just a variable that hold the address of a pointer - it's really no different from any other pointer. Here's an example:
    Code:
    int x = 7;
    int *px = &x;        // px contains the address of x. 
    int **ppx = &px;    // ppx contains the address of px. 
    int y = 5; 
    int *py = &y;
    
    **ppx = 8;   // Changes x to 8
    
    *ppx = py;  // Now px points to py
    **ppx = 9;   // y is now set to 9.
    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #19
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    Perhaps why people have so much difficulty with pointers is because they don't actually know what the operators do... They understand the idea however.

  5. #20
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by zacs7 View Post
    Perhaps why people have so much difficulty with pointers is because they don't actually know what the operators do... They understand the idea however.
    It took me quite some time to understand pointers too - even after programming quite a bit of assembler. If you found it easy, then that's great, but it's not an entirely trivial subject.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #21
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    23,031
    Certainly would be worth investigating.
    Mostly they don't understand the principles behind pointers. They're just taught that to pass an argument to a function, do this and so.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #22
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    I'm not saying I didn't find pointers tough, it's just a what I've noticed

  8. #23
    Registered User
    Join Date
    Apr 2008
    Posts
    31

    Arrow char ** for void type?

    Quote Originally Posted by zacs7 View Post
    If you fully understand pointers, understanding pointers-to-pointers should be no problem.

    Pointers only hold an address to something else, think of it like man pointing to something. Consider the following, let man = pointer.

    Code:
    [man 0] -> [man 1] -> [man 2] -> [the man you want]
    You want to remember where [the man you want] is,
    * so you tell man 2 to remember where he is,
    * you tell man 1 to remember where man 2 is
    * you tell man 0 to remember where man 1 is

    If you want to find [the man you want] you can either,
    1. ask man 0 where man 1 is (see 2.)
    2. ask man 1 where man 2 is (see 3.)
    3. ask man 2 where [the man you want] is.

    You can of course skip to 2 or 3 or even straight to the man.

    I hope my corny example made it clear

    I already know all of the above but, what's the use of (char **)???
    p1 & p2 are pointers to "VOID"...
    Do we have to use (char **) casting for all the "VOID" argument types? or does it depend on the arguments passed to the function?


    Code:
    int compare (const void *p1, const void *p2)
    {
      const char *i;
      const char *j;
    
      i = *((char **)p1); //IF p1 & p2 are strings... what am I doing here?
      j = *((char **)p2);

  9. #24
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    23,031
    Void* is a special type of pointer that can hold an address to anything. In our examples, we just converted a const char** pointer into void*. So when we later want to get it back, we cast it to char** and then dereference to get char*.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #25
    Registered User
    Join Date
    Apr 2008
    Posts
    31

    Exclamation

    Quote Originally Posted by Elysia View Post
    Void* is a special type of pointer that can hold an address to anything. In our examples, we just converted a const char** pointer into void*. So when we later want to get it back, we cast it to char** and then dereference to get char*.
    Anyone can draw a diagram of this?

    From what I understand, "void *" is just a generalized function argument, it can take any type of pointer.

    Also, in qsort... why is it written only "compare"(the fucntion whose code I posted above) instead of compare(arguments)...
    Code:
    qsort((void *)words, wordCount, sizeof(char *), compare);

  11. #26
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    23,031
    Quote Originally Posted by terminator View Post
    From what I understand, "void *" is just a generalized function argument, it can take any type of pointer.
    That is exactly what it is. A generic type of pointer that can hold anything. You can't dereference void, for example, because it can hold anything. So the compiler doesn't even know what it is.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  12. #27
    Registered User
    Join Date
    Apr 2008
    Posts
    31

    Question example

    Quote Originally Posted by Elysia View Post
    That is exactly what it is. A generic type of pointer that can hold anything. You can't dereference void, for example, because it can hold anything. So the compiler doesn't even know what it is.
    Is this how it works???

    Code:
    char **c;
    char **d;
    *c[0] = "I am a string";
    *d[0] = "I am also a string";
    
    Now, we pass these two char** as arguments of function:
    
    int compare(const void *p, const void *q)
    {
    const char * c = *((char **) p);
    const char * j = *((char **) q);
    
    do stuff with above strings....
    }

  13. #28
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Posts
    23,031
    No, see my example. You are using unallocated memory (you DID read the article and it DID explain that).
    You are also confused about operator precedence.
    Plus you are confusing char with char*.
    It should be
    *c = "I am a string";

    (*c)[0] = char
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  14. #29
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Quote Originally Posted by iMalc View Post
    Nope, the second one is completely wrong. You can't subtract the *'s. This function is obviously being used as an argument to qsort which is to sort an array of char*'s a.k.a strings.

    Original code: The *'s in the cast itself don't do anything besides tell the compiler what type of thing the void pointer is supposed to be. This doesn't generate any code whatsoever. The outer star on the left actually tells the compiler to dereference the thing on the right. That means asking the compiler to generate code that fetches what is at some memory address, and viola you have correct code. There is no simpler way to do this. It must cast to a char**!

    Your incorrect code: The single char* cast tells the compiler (incorrectly) that the data is already a char pointer. This in itself generates no code at all. It does not look up and memory address to get the correct pointer value, and will produce non-working code.

    Even Dave_Sinkula seems to have misunderstood this one, going by his first comment - Must be having an off day.
    King Mir has a good explanation.
    OK, I think I see now... I would have expected a void** in that case; but if it's a function pointer for qsort(), I guess you'd have to do it like that.

  15. #30
    Registered User
    Join Date
    Apr 2008
    Posts
    31

    Question Example Of Char **

    Code:
    int main( )
    {
      char *words[ ] = { "Then",   "he",   "shouted", "What", "I",
                        "didn't", "hear", "what",    "you",  "said" };
      int j = 0;
      int n = sizeof(words) / sizeof(char *);
    
      qsort( words, n, sizeof(char *), strptrcmp );
    
      for ( j = 0 ; j < n ; j++ )
        puts( words[j] );
    }
    
    int strptrcmp( const void *sp1, const void *sp2 )
    // Compare two strings by reference.
    {
      // qsort( ) passes a pointer to the pointer:
      // dereference it to pass a char * to strcmp.
      const char * s1 = *(char **)sp1;
      const char * s2 = *(char **)sp2;
      return strcmp( s1, s2 );
    }
    When I compile this code as
    Code:
    const char *s1 = *(char **) sp1;
    const char *s2 = *(char **) sp2;
    I get the compiler error...

    initialization makes pointer from integer without a cast

    What does it mean?

Page 2 of 4 FirstFirst 1234 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. casting contents of pointer?
    By nutsNguts in forum C Programming
    Replies: 8
    Last Post: 11-10-2008, 11:07 AM
  2. Ban pointers or references on classes?
    By Elysia in forum C++ Programming
    Replies: 89
    Last Post: 10-30-2007, 04:20 AM
  3. scope of a pointer?
    By Syneris in forum C++ Programming
    Replies: 6
    Last Post: 12-29-2005, 09:40 PM
  4. Question About Pointer To Pointer
    By BlitzPackage in forum C++ Programming
    Replies: 2
    Last Post: 09-19-2005, 11:19 PM
  5. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21