argument returning

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • josh

    #1

    argument returning

    Hi, I'm converting (for learning purpose) )a program from Java to C++
    and I've a doubt:

    In Java every argument (variable and reference types) is passed and
    returned in functions by-value so if I want to create inside that
    function a matrix (i.e. int a[][]) and than passing the reference to it
    I can simply
    returning that value:

    in main()
    ....
    int z[][] = pass(); // here 'z' contain the reference to the array
    object created in pass() by 'a'
    ....

    the method
    ....
    public static int[][] pass()
    {
    int a[][] = {{1,2},{3,4}};
    return a;
    }
    ....

    instead in C++

    in main()
    ....
    int **p = pass();
    ....

    the function
    ....
    int ** pass()
    {
    static int z[] = {1,2,3, -1};
    static int o[] = {4,5,6,7, -1};
    static int j[] = {8,9,10,11,12, -1};

    static int *p[3];

    p[0] = z;
    p[1] = o;
    p[2] = j;

    return p;
    }
    ....

    in the C++ if I don't use the static when I go out from that function
    in the caller 'p' has not
    the correct array values. In C++ the argument can be passed by-value
    and by-reference so
    when in the function I call 'return p' is passed its address but if I
    don't use static that address is
    not more available bacause 'p' is not more available....

    is that the correct conversion ?

    Thanks

  • lwz

    #2
    Re: argument returning

    It works for me without static... :)

    josh wrote:
    Hi, I'm converting (for learning purpose) )a program from Java to C++
    and I've a doubt:
    >
    In Java every argument (variable and reference types) is passed and
    returned in functions by-value so if I want to create inside that
    function a matrix (i.e. int a[][]) and than passing the reference to it
    I can simply
    returning that value:
    >
    in main()
    ...
    int z[][] = pass(); // here 'z' contain the reference to the array
    object created in pass() by 'a'
    ...
    >
    the method
    ...
    public static int[][] pass()
    {
    int a[][] = {{1,2},{3,4}};
    return a;
    }
    ...
    >
    instead in C++
    >
    in main()
    ...
    int **p = pass();
    ...
    >
    the function
    ...
    int ** pass()
    {
    static int z[] = {1,2,3, -1};
    static int o[] = {4,5,6,7, -1};
    static int j[] = {8,9,10,11,12, -1};
    >
    static int *p[3];
    >
    p[0] = z;
    p[1] = o;
    p[2] = j;
    >
    return p;
    }
    ...
    >
    in the C++ if I don't use the static when I go out from that function
    in the caller 'p' has not
    the correct array values. In C++ the argument can be passed by-value
    and by-reference so
    when in the function I call 'return p' is passed its address but if I
    don't use static that address is
    not more available bacause 'p' is not more available....
    >
    is that the correct conversion ?
    >
    Thanks

    Comment

    • josh

      #3
      Re: argument returning


      lwz ha scritto:
      It works for me without static... :)
      Sorry but it's not possible:

      try this, eliminating static

      int main()
      {
      int **p = pass();

      for(int ix=0; ix < 3; ix++)
      {
      int *row = *(p+ix);

      for(int iy=0; *(row+iy) != -1; iy++)
      printf(" %d ", *(row+iy));
      }
      printf("\n");
      }

      if you try to compile the compiler show a warning:
      warning: address of local variable 'p' returned cpp_test
      and in fact the output shows trashing values......

      Comment

      • Boris

        #4
        Re: argument returning

        josh wrote:
        Hi, I'm converting (for learning purpose) )a program from Java to C++
        and I've a doubt:
        >
        In Java every argument (variable and reference types) is passed and
        returned in functions by-value so if I want to create inside that
        function a matrix (i.e. int a[][]) and than passing the reference to
        it I can simply
        returning that value:
        [...]
        in the C++ if I don't use the static when I go out from that function
        in the caller 'p' has not
        the correct array values. In C++ the argument can be passed by-value
        and by-reference so
        when in the function I call 'return p' is passed its address but if I
        don't use static that address is
        not more available bacause 'p' is not more available....
        >
        is that the correct conversion ?
        Yes, that's true. In Java the garbage collector will not release the
        variable as there is a reference passed around. In C++ the variable will be
        released if it goes out of scope - which means for local variables when the
        function returns. You must use static then (which might cause new problems
        though in multithreaded programs).

        Boris


        Comment

        • josh

          #5
          Re: argument returning


          Boris ha scritto:
          Yes, that's true. In Java the garbage collector will not release the
          variable as there is a reference passed around.
          not just... the object created on the heap is not released because
          there is 'z'
          that is pointing to but the variable 'a' when the function return is
          not more available :)

          Comment

          • peter koch

            #6
            Re: argument returning


            josh wrote:
            Hi, I'm converting (for learning purpose) )a program from Java to C++
            and I've a doubt:
            >
            In Java every argument (variable and reference types) is passed and
            returned in functions by-value
            Well - sort of. Remember that in Java, you can not declare an object -
            only a reference:

            //JAVA code (sorry!)
            Object obj = new Object;

            Here obj is not an object but a reference to an object. This
            corresponds to the following C++ code:
            Object* obj = new Object;

            so if I want to create inside that
            function a matrix (i.e. int a[][]) and than passing the reference to it
            I can simply
            returning that value:
            >
            in main()
            ...
            int z[][] = pass(); // here 'z' contain the reference to the array
            object created in pass() by 'a'
            ...
            >
            the method
            ...
            public static int[][] pass()
            {
            int a[][] = {{1,2},{3,4}};
            return a;
            }
            ...
            >
            instead in C++
            >
            in main()
            ...
            int **p = pass();
            Here you're wrong. There is a difference between a pointer and a
            matrix, and in C/C++ you can not return an array (and thus not a
            matrix).

            What you should do is find out what you want to return and declare that
            type, e.g.
            typedef std::vector<std ::vector<int matrix;

            (Depending on what you do return the above might be overkill. If e.g.
            you always return a 2*2 integer matrix, the above is overkill).
            ...
            >
            the function
            ...
            int ** pass()
            now becomes
            matrix pass()
            {
            matrix result;

            ....
            return result;
            }
            {
            static int z[] = {1,2,3, -1};
            static int o[] = {4,5,6,7, -1};
            static int j[] = {8,9,10,11,12, -1};
            >
            static int *p[3];
            >
            p[0] = z;
            p[1] = o;
            p[2] = j;
            >
            return p;
            }
            ...
            >
            in the C++ if I don't use the static when I go out from that function
            in the caller 'p' has not
            the correct array values. In C++ the argument can be passed by-value
            and by-reference so
            when in the function I call 'return p' is passed its address but if I
            don't use static that address is
            not more available bacause 'p' is not more available....
            >
            is that the correct conversion ?
            The real problem is that what you point to has been deallocated at
            return - it does not exist anymore. You "resolve" this by using static
            memory, but other problems come up - e.g. that you can not use pass()
            when multithreading and each call to pass destroys any previously
            returned values.

            /Peter

            Comment

            • josh

              #7
              Re: argument returning


              peter koch ha scritto:
              Here you're wrong. There is a difference between a pointer and a
              matrix,
              yes there is a difference in fact a matrix is not a pointer but a
              pointer to an array
              i.e. if I have int a[2][2] I can pass it to a function writing:
              1) foo(int a[][2]) or
              2) foo(int (*a)[2])
              >and in C/C++ you can not return an array (and thus not a
              matrix).
              no I can return an array:
              int * foo()
              {
              static int a[3] = {1,2,3};
              return a;
              }
              and so I can return a matrix initializating it as a triangular array ad
              so like an array of pointers
              and so the function:
              int ** foo()
              {
              static int z[] = {1,2,3, -1};
              static int o[] = {4,5,6,7, -1};
              static int j[] = {8,9,10,11,12, -1};

              static int *p[3];

              p[0] = z;
              p[1] = o;
              p[2] = j;

              return p;
              }
              is legal!

              Comment

              • peter koch

                #8
                Re: argument returning


                josh wrote:
                peter koch ha scritto:
                >
                Here you're wrong. There is a difference between a pointer and a
                matrix,
                >
                yes there is a difference in fact a matrix is not a pointer but a
                pointer to an array
                i.e. if I have int a[2][2] I can pass it to a function writing:
                1) foo(int a[][2]) or
                2) foo(int (*a)[2])
                No you can not. You are not passing the matrix to a function - what you
                are passing is a pointer to the first element. I believe it must be
                your Java background that confuses you.
                >
                and in C/C++ you can not return an array (and thus not a
                matrix).
                no I can return an array:
                int * foo()
                This is not a array! It is a pointer to an integer - for Christs sake.
                {
                static int a[3] = {1,2,3};
                return a;
                }
                and so I can return a matrix initializating it as a triangular array ad
                You are not returning a matrix. What you are returning is a pointer to
                the first element. If you can not understand that, I must strongly
                recommend you to stop programming in C (or C++ if thats what you call
                it).
                so like an array of pointers
                and so the function:
                int ** foo()
                {
                static int z[] = {1,2,3, -1};
                static int o[] = {4,5,6,7, -1};
                static int j[] = {8,9,10,11,12, -1};
                >
                static int *p[3];
                >
                p[0] = z;
                p[1] = o;
                p[2] = j;
                >
                return p;
                }
                is legal!
                It has nothing to do with legality.

                /Peter

                Comment

                • josh

                  #9
                  Re: argument returning


                  peter koch ha scritto:
                  >
                  No you can not. You are not passing the matrix to a function - what you
                  are passing is a pointer to the first element. I believe it must be
                  your Java background that confuses you.
                  sorry my first language is not english so for me is difficult to
                  explain my concepts.
                  I did not want to say that I can pass an array or a matrix because a
                  pointer is
                  different from that objects. I wanted only say that as in C/C++ I can't
                  pass an
                  array or a matrix with the sintax i.e. int [] or int [][] I can receive
                  them using
                  pointer notation.

                  Also in Java we don't pass array or matrix directly but we pass a
                  reference of
                  the array object created.

                  Comment

                  • peter koch

                    #10
                    Re: argument returning


                    josh wrote:
                    peter koch ha scritto:
                    >

                    No you can not. You are not passing the matrix to a function - what you
                    are passing is a pointer to the first element. I believe it must be
                    your Java background that confuses you.
                    >
                    sorry my first language is not english so for me is difficult to
                    explain my concepts.
                    I did not want to say that I can pass an array or a matrix because a
                    pointer is
                    different from that objects. I wanted only say that as in C/C++ I can't
                    pass an
                    array or a matrix with the sintax i.e. int [] or int [][] I can receive
                    them using
                    pointer notation.
                    You can receive their adress by returning the pointer. But this is a
                    very bad idea so change it to std::vector (unless you want to spend
                    long hours debugging the situation).
                    >
                    Also in Java we don't pass array or matrix directly but we pass a
                    reference of
                    the array object created.
                    Correct, but the situation is not the same here: in Java you create the
                    initial object with new, so the object has dynamic allocation from the
                    beginning. Unless you install a garbage-collector with C++ you can not
                    do the same thing - your program will leak.

                    /Peter

                    Comment

                    Working...