C passing a global pointer

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • aaa bbb
    New Member
    • Feb 2012
    • 7

    C passing a global pointer

    Hi guys.
    Let's say I've got something like this:

    struct Box{
    //something
    };
    typedef struct Box* pBox;

    void fun(pBox p);

    int main(){
    pBox p = NULL;
    fun(p);
    }

    void fun(pBox p){
    if(p == NULL) p = (pBox)malloc(si zeof(Box));
    }

    function fun recieves the address(which is NULL) and then allocates the memory for the Box; Let's say I cannot return the address of new allocated p and I can't also use that pointer p(from main) without passing it into a function.

    Q: How can I make it that I could operate in function "fun" as I operate on orginal pointer p(from main), right now I'm just passing the address to my function but I can't change
    the 'global' pointer p ;(.

    I remember in pascal it's like:
    "function(v ar pointer:[pointer to sth])"
    and all is done.

    How can I do it in C?
    Any ideas?
  • johny10151981
    Top Contributor
    • Jan 2010
    • 1059

    #2
    Read About IPC. there is lots of way to do this.

    Comment

    • weaknessforcats
      Recognized Expert Expert
      • Mar 2007
      • 9214

      #3
      This function:

      Code:
      void fun(pBox p){
      etc...
      makes a copy of the pointer used by the caller. What you want to do is tell the compiler to not make that copy. In C++ that is called a reference:

      Code:
      void fun(pBox& p){
      etc...
      Now in fun, the argument p is the same pointer used by the calling function. No copy was made.

      Comment

      • aaa bbb
        New Member
        • Feb 2012
        • 7

        #4
        I tried "pBox& p" but it says:
        'expected ';', ',', ')' before '&' token.
        I'm nut sure if I can do that,
        isn't it like "Box* &p"?...

        Guess it's not available in C. So it's not possible to use in function 'original' pointer?(not using global pointer in functions, gotta pass them first)

        Comment

        • weaknessforcats
          Recognized Expert Expert
          • Mar 2007
          • 9214

          #5
          Did you change both the function and the prototype?

          Here is your code with the change and it compiles OK:
          Code:
          struct Box{
           //something
           };
           typedef struct Box* pBox;
           
          void fun(pBox& p);
           
          int main(){
           pBox p = NULL;
           fun(p);
           }
           
          void fun(pBox& p){
           if(p == NULL) p = (pBox)malloc(sizeof(Box));
           }

          Comment

          • Banfa
            Recognized Expert Expert
            • Feb 2006
            • 9067

            #6
            Code:
            void fun(pBox& p)
            This doesn't work because it is a reference which is only supported by C++, a solution in C is required. And that is simple, just use a pointer to a pointer.

            Whenever you want to output some type but not use the return value you need a pointer to that type in your function prototype, for int

            Code:
            int main()
            {
              int a;
            
              getValue(&a);
            
              printf("The value is: %d\n", a);
            
              return 0;
            }
            
            void getValue(int* pValue)
            {
              *pValue = 10;
            }
            This is true for any type and can generalised for any type A as


            Code:
            void getValue(A* pValue)
            {
              *pValue = <ValidValueForTypeA>;
            }
            In your case you want to pass out a variable of type pBox so in the code above A = pBox and you need this prototype void fun(pBox* p).

            In full your function becomes

            Code:
            void fun(pBox* p)
            {
              if(*p == NULL)
              {
                *p = malloc(sizeof(Box));
              }
            }
            Note the is no need and indeed it can cause subtle errors if you cast the return value of malloc in C.

            Comment

            • weaknessforcats
              Recognized Expert Expert
              • Mar 2007
              • 9214

              #7
              Code:
              fun(pBox* p)
               2. {
               3.   if(*p == NULL)
               4.   {
               5.     *p = malloc(sizeof(Box));
               6.   }
               7. }
              This won't work because p is a Box* so *p s a Box.

              I believe you want:
              Code:
              fun(pBox** p)
                {
                 if(*p == NULL)
                  {
                    *p = malloc(sizeof(Box));
                 }
                }
              Now p is a pointer to a Box* so *p is now a Box*.

              Comment

              • Banfa
                Recognized Expert Expert
                • Feb 2006
                • 9067

                #8
                This won't work because p is a Box* so *p s a Box.
                No p is pBox* and pBox is typedef'd to Box*, making p a Box**, just what is wanted. If you use pBox** p then p would be Box*** which would be indirection gone mad :D
                Last edited by Banfa; Mar 7 '12, 09:32 AM. Reason: Removed an e

                Comment

                • aaa bbb
                  New Member
                  • Feb 2012
                  • 7

                  #9
                  why does it give me runtime error when I try go with '*p == NULL'?

                  Comment

                  • Banfa
                    Recognized Expert Expert
                    • Feb 2006
                    • 9067

                    #10
                    You probably call the function with the wrong variable type, you are trying to write a variable of type pBox so you need to declare a pBox in main.

                    Comment

                    • aaa bbb
                      New Member
                      • Feb 2012
                      • 7

                      #11
                      okay, what I do wrong?:

                      Code:
                      typedef struct {
                       int n;
                      }Box;
                      typedef struct Box* pBox;
                      
                      void fun(pBox* p)
                      {
                        if(*p == NULL)
                        {
                          *p = malloc(sizeof(Box));
                        }
                      }
                       int main(){
                      	pBox p = NULL;
                      	fun(p);
                      }
                      still got that error in '*p == NULL', can someone compile this and check, it kills me...
                      Last edited by Banfa; Mar 7 '12, 09:33 AM.

                      Comment

                      • weaknessforcats
                        Recognized Expert Expert
                        • Mar 2007
                        • 9214

                        #12
                        You need to #include <stdio.h> in order to get NULL declared.

                        You may have other warnings which indicate a weakness in the code. Ideally, you should have no errors and no warnings.

                        Comment

                        • aaa bbb
                          New Member
                          • Feb 2012
                          • 7

                          #13
                          yes, I included libs but the problem comes when I run the program.
                          It appears runtime error and points the line with NULL. But I guess it's sth wrong with the *p == null because when I change it to 'p' it works.

                          Comment

                          • Banfa
                            Recognized Expert Expert
                            • Feb 2006
                            • 9067

                            #14
                            Do you not get any warnings when you compile? I get the following warning compiling your code

                            bytes.c:15: warning: passing argument 1 of 'fun' from incompatible pointer type

                            You should not ignore compiler warnings, they are there to tell you when you are doing something suspect. This is one of those cases where C++ is stricter than C it would not allow that line to compile, it produces an error rather than a warning. However that is correct the compiler assumes you know what you are doing and allow the pointer conversion to go ahead.

                            So you pass p of type Box* to a function expecting Box**. p has the value NULL or 0 and the first thing you do is dereference it at line 8 since it is NULL the program crashes.

                            The warning highlights the problem, you passed type Box* to a function expecting Box**, you passed the wrong thing, you needed to dereference the pointer you were passing as the example in my first post when you want to output an int the function takes int* and you pass &a (where a is an int variable). The function is expecting pBox* so you pass &p (where p is a pBox variable).

                            i.e. line 15 should be fun(&p);

                            Don't ignore compiler warnings and if you didn't get a warning get a better compiler.

                            Comment

                            • aaa bbb
                              New Member
                              • Feb 2012
                              • 7

                              #15
                              Oh, now I see... should have read your previous reply better. And thanks for advice with the warnings, I simply didn't care what they said thinking it's not the case of my problem.
                              Thanks for help. ;D

                              Comment

                              Working...