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. Passing an array as argument to a function

Passing an array as argument to a function

Scheduled Pinned Locked Moved C / C++ / MFC
questiondata-structures
61 Posts 7 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.
  • C Calin Negru

    thanks Greg for that tip

    Greg UtasG Offline
    Greg UtasG Offline
    Greg Utas
    wrote on last edited by
    #23

    I made a mistake. See Richard's post below.

    Robust Services Core | Software Techniques for Lemmings | Articles

    <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
    <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

    C 1 Reply Last reply
    0
    • Greg UtasG Greg Utas

      I made a mistake. See Richard's post below.

      Robust Services Core | Software Techniques for Lemmings | Articles

      C Offline
      C Offline
      Calin Negru
      wrote on last edited by
      #24

      noticed

      1 Reply Last reply
      0
      • Greg UtasG Greg Utas

        Right you are! I forget to remove the *.

        Robust Services Core | Software Techniques for Lemmings | Articles

        L Offline
        L Offline
        Lost User
        wrote on last edited by
        #25

        Why not leave the * but remove the []? The parameter is a pointer to an array, not an actual array.

        Greg UtasG 1 Reply Last reply
        0
        • L Lost User

          Why not leave the * but remove the []? The parameter is a pointer to an array, not an actual array.

          Greg UtasG Offline
          Greg UtasG Offline
          Greg Utas
          wrote on last edited by
          #26

          I use brackets to indicate that the underlying is an array, not a pointer to a single char. Maybe it's because I was a latecomer to C++ and never used C idioms, another one being if(p), for which I write if(p != nullptr).

          Robust Services Core | Software Techniques for Lemmings | Articles

          <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
          <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

          L 1 Reply Last reply
          0
          • Greg UtasG Greg Utas

            I use brackets to indicate that the underlying is an array, not a pointer to a single char. Maybe it's because I was a latecomer to C++ and never used C idioms, another one being if(p), for which I write if(p != nullptr).

            Robust Services Core | Software Techniques for Lemmings | Articles

            L Offline
            L Offline
            Lost User
            wrote on last edited by
            #27

            A pointer rarely means a pointer to a single item, it always indicates a pointer to a set of items. If you want to pass a single int, char etc, then why use a pointer? I would agree with you on using the if(p != nullptr) construct, it makes it much clearer.

            Greg UtasG K 2 Replies Last reply
            0
            • L Lost User

              A pointer rarely means a pointer to a single item, it always indicates a pointer to a set of items. If you want to pass a single int, char etc, then why use a pointer? I would agree with you on using the if(p != nullptr) construct, it makes it much clearer.

              Greg UtasG Offline
              Greg UtasG Offline
              Greg Utas
              wrote on last edited by
              #28

              Richard MacCutchan wrote:

              If you want to pass a single int, char etc, then why use a pointer?

              Because it might inadvertently be nullptr, and I find this defensive code jarring:

              void f(type& t)
              {
              if(&t ! nullptr)...
              }

              The optimize-everything crowd won't agree, but in my opinion code that invokes the above with a null reference should suffer a SIGSEGV before the function is called. But since that's not the case...

              Robust Services Core | Software Techniques for Lemmings | Articles

              <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
              <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

              L 1 Reply Last reply
              0
              • L Lost User

                A pointer rarely means a pointer to a single item, it always indicates a pointer to a set of items. If you want to pass a single int, char etc, then why use a pointer? I would agree with you on using the if(p != nullptr) construct, it makes it much clearer.

                K Offline
                K Offline
                k5054
                wrote on last edited by
                #29

                Richard MacCutchan wrote:

                f you want to pass a single int, char etc, then why use a pointer?

                On occasion you want an "out" or sentinel parameter, so in those cases you have to use a pointer (or a reference if using C++). There's lots of cases where you might have a pointer to a single struct that you either want to fill in, or avoid copying the whole thing to the stack. For the latter, of course, you'd mark it as const.

                Keep Calm and Carry On

                1 Reply Last reply
                0
                • L Lost User

                  Greg Utas wrote:

                  char* somedata[]

                  That's an array of pointers.

                  C Offline
                  C Offline
                  Calin Negru
                  wrote on last edited by
                  #30

                  how do you declare and access an array of pointers? if you want to cycle through pointers of same type in a for loop.

                  int * somedata[] = new int * [5]; ??

                  "DreamLand Page" on facebook

                  K 2 Replies Last reply
                  0
                  • C Calin Negru

                    how do you declare and access an array of pointers? if you want to cycle through pointers of same type in a for loop.

                    int * somedata[] = new int * [5]; ??

                    "DreamLand Page" on facebook

                    K Offline
                    K Offline
                    k5054
                    wrote on last edited by
                    #31

                    In that case you'd use another level of indirection: e.g.

                    #include <iostream>

                    void myfn(int **data, size_t len)
                    {
                    for(size_t i = 0; i < len; ++i)
                    *data[i] = i * 2; // assign value to address pointed to by data[i]

                    //  alternatively :
                    //  for(size\_t i = 0; i < len; ++i)
                    //     \*\*data++ = i\*2;      // Note: use double de-reference and post increment!
                    

                    }

                    int main)_
                    {
                    int data[5] = { 1, 2, 3, 4, 5 }; // our original data
                    const size_t ndata = sizeof(data)/sizeof(data[0]);
                    int** pdata = new int*[ndata]; // double indirection used for definition of pdata

                    // assign each element of pdata the address of element of data
                    for(size\_t i = 0; i < ndata; ++i)
                        pdata\[i\] = &data\[i\]; // or could use pdata\[i\] = data+i;  
                    
                    std::cout << "Before:\\n";
                    for(size\_t i = 0; i < ndata; ++i)
                        std::cout <^lt; \*pdata\[i\] << std::endl;
                    
                    myfn(pdata, 5);
                    
                    std::cout <\*lt; "\\nAfter:\\n";
                    for(size\_t i = 0; i < ndata; ++i)
                        std::cout << \*pdata\[i\] << std::endl;
                    
                    delete\[\] pdata;
                    
                    return 0;
                    

                    }

                    Keep Calm and Carry On

                    C 2 Replies Last reply
                    0
                    • C Calin Negru

                      how do you declare and access an array of pointers? if you want to cycle through pointers of same type in a for loop.

                      int * somedata[] = new int * [5]; ??

                      "DreamLand Page" on facebook

                      K Offline
                      K Offline
                      k5054
                      wrote on last edited by
                      #32

                      #include ;

                      void myfn(int **data, size_t len)
                      {
                      for(size_t i = 0; i < len; ++i)
                      *data[i] = i * 2; // comment

                      // comment
                      // more comment
                      

                      }

                      Keep Calm and Carry On

                      1 Reply Last reply
                      0
                      • K k5054

                        I didn't know about _countof(). Is it an MS only extension? Trying to compile with gcc under linux produces an implicit declaration warning in C and a not declared in this scope in C++

                        Keep Calm and Carry On

                        L Offline
                        L Offline
                        leon de boer
                        wrote on last edited by
                        #33

                        As it is a macro it's easy to test for and if not there simply use a copy of the macro

                        #if !defined(_countof)
                        #define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
                        #endif

                        In vino veritas

                        1 Reply Last reply
                        0
                        • Greg UtasG Greg Utas

                          Richard MacCutchan wrote:

                          If you want to pass a single int, char etc, then why use a pointer?

                          Because it might inadvertently be nullptr, and I find this defensive code jarring:

                          void f(type& t)
                          {
                          if(&t ! nullptr)...
                          }

                          The optimize-everything crowd won't agree, but in my opinion code that invokes the above with a null reference should suffer a SIGSEGV before the function is called. But since that's not the case...

                          Robust Services Core | Software Techniques for Lemmings | Articles

                          L Offline
                          L Offline
                          Lost User
                          wrote on last edited by
                          #34

                          I don't think a reference can ever be null.

                          Greg UtasG 1 Reply Last reply
                          0
                          • L Lost User

                            I don't think a reference can ever be null.

                            Greg UtasG Offline
                            Greg UtasG Offline
                            Greg Utas
                            wrote on last edited by
                            #35

                            It's true that C++ has no explicit notion of a null reference. But if you run this

                            void test(int& i)
                            {
                            if(i == 1)
                            std::cout << i << '\n';
                            }

                            int main(int argc, char* argv[])
                            {
                            int* pi = nullptr;
                            test(*pi);
                            }

                            it will SIGSEGV on the line if(i == 1). That's in a VS2017 debug build.

                            Robust Services Core | Software Techniques for Lemmings | Articles

                            <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
                            <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

                            L 1 Reply Last reply
                            0
                            • Greg UtasG Greg Utas

                              It's true that C++ has no explicit notion of a null reference. But if you run this

                              void test(int& i)
                              {
                              if(i == 1)
                              std::cout << i << '\n';
                              }

                              int main(int argc, char* argv[])
                              {
                              int* pi = nullptr;
                              test(*pi);
                              }

                              it will SIGSEGV on the line if(i == 1). That's in a VS2017 debug build.

                              Robust Services Core | Software Techniques for Lemmings | Articles

                              L Offline
                              L Offline
                              Lost User
                              wrote on last edited by
                              #36

                              That is interesting. It should really crash at the test(*pi); line, since it is trying to dereference a null pointer. I would also suggest the the compiler should recognise that pi is a pointer and not a reference.

                              Greg UtasG 1 Reply Last reply
                              0
                              • L Lost User

                                That is interesting. It should really crash at the test(*pi); line, since it is trying to dereference a null pointer. I would also suggest the the compiler should recognise that pi is a pointer and not a reference.

                                Greg UtasG Offline
                                Greg UtasG Offline
                                Greg Utas
                                wrote on last edited by
                                #37

                                I agree that it should crash there. But I've never seen it work that way, though for most of my career I worked in a language where it would have crashed there. It's not unusual to dereference a pointer (pi) and pass it to an argument that wants a reference.

                                Robust Services Core | Software Techniques for Lemmings | Articles

                                <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
                                <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

                                L 1 Reply Last reply
                                0
                                • Greg UtasG Greg Utas

                                  I agree that it should crash there. But I've never seen it work that way, though for most of my career I worked in a language where it would have crashed there. It's not unusual to dereference a pointer (pi) and pass it to an argument that wants a reference.

                                  Robust Services Core | Software Techniques for Lemmings | Articles

                                  L Offline
                                  L Offline
                                  Lost User
                                  wrote on last edited by
                                  #38

                                  Greg Utas wrote:

                                  It's not unusual ...

                                  Interesting, but not something I have ever done. I had (naively) assumed that the whole point of references was to avoid this very trap. Incidentally I tried it in g++ as well and the gave a SEGV.

                                  Greg UtasG 1 Reply Last reply
                                  0
                                  • L Lost User

                                    Greg Utas wrote:

                                    It's not unusual ...

                                    Interesting, but not something I have ever done. I had (naively) assumed that the whole point of references was to avoid this very trap. Incidentally I tried it in g++ as well and the gave a SEGV.

                                    Greg UtasG Offline
                                    Greg UtasG Offline
                                    Greg Utas
                                    wrote on last edited by
                                    #39

                                    Where did it die in g++? Before or after calling the function?

                                    Robust Services Core | Software Techniques for Lemmings | Articles

                                    <p><a href="https://github.com/GregUtas/robust-services-core/blob/master/README.md">Robust Services Core</a>
                                    <em>The fox knows many things, but the hedgehog knows one big thing.</em></p>

                                    L 1 Reply Last reply
                                    0
                                    • Greg UtasG Greg Utas

                                      Where did it die in g++? Before or after calling the function?

                                      Robust Services Core | Software Techniques for Lemmings | Articles

                                      L Offline
                                      L Offline
                                      Lost User
                                      wrote on last edited by
                                      #40

                                      Same as in Windows, on the if statement in test function.

                                      K 1 Reply Last reply
                                      0
                                      • L Lost User

                                        Same as in Windows, on the if statement in test function.

                                        K Offline
                                        K Offline
                                        k5054
                                        wrote on last edited by
                                        #41

                                        Ditto for clang 9.0.1 (Fedora fc31)

                                        Keep Calm and Carry On

                                        1 Reply Last reply
                                        0
                                        • K k5054

                                          In that case you'd use another level of indirection: e.g.

                                          #include <iostream>

                                          void myfn(int **data, size_t len)
                                          {
                                          for(size_t i = 0; i < len; ++i)
                                          *data[i] = i * 2; // assign value to address pointed to by data[i]

                                          //  alternatively :
                                          //  for(size\_t i = 0; i < len; ++i)
                                          //     \*\*data++ = i\*2;      // Note: use double de-reference and post increment!
                                          

                                          }

                                          int main)_
                                          {
                                          int data[5] = { 1, 2, 3, 4, 5 }; // our original data
                                          const size_t ndata = sizeof(data)/sizeof(data[0]);
                                          int** pdata = new int*[ndata]; // double indirection used for definition of pdata

                                          // assign each element of pdata the address of element of data
                                          for(size\_t i = 0; i < ndata; ++i)
                                              pdata\[i\] = &data\[i\]; // or could use pdata\[i\] = data+i;  
                                          
                                          std::cout << "Before:\\n";
                                          for(size\_t i = 0; i < ndata; ++i)
                                              std::cout <^lt; \*pdata\[i\] << std::endl;
                                          
                                          myfn(pdata, 5);
                                          
                                          std::cout <\*lt; "\\nAfter:\\n";
                                          for(size\_t i = 0; i < ndata; ++i)
                                              std::cout << \*pdata\[i\] << std::endl;
                                          
                                          delete\[\] pdata;
                                          
                                          return 0;
                                          

                                          }

                                          Keep Calm and Carry On

                                          C Offline
                                          C Offline
                                          Calin Negru
                                          wrote on last edited by
                                          #42

                                          thanks k5054

                                          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