Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    passing arrays as parameters

    SDK Help
    0
    26
    14.4k
    Loading More Posts
    • 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.
    • H
      Helper
      last edited by

      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

      On 29/03/2012 at 20:01, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:   13 
      Platform:      
      Language(s) :     C++  ;

      ---------
      in c# i can do the following:

      float foo (int myarray[]) {
      }
      ...
      foo(new float[] {0.1,0.2,0.3})
      

      trying the same with real & long in c++ doesn't work, the compiler doesn't seem to understand this
      construction. i cannot find any example / information on this. is this a limitation of long & real or isn't
      it possible to pass parameters with the new statement. if it is, how it is done ?

      thank you for your patience 😄

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

        On 29/03/2012 at 22:30, xxxxxxxx wrote:

        http://www.fredosaurus.com/notes-cpp/arrayptr/array-initialization.html

        You can use memcpy on a stack-allocated array to copy it's values to a heap-allocated array if necessary. Note that you will get memory leaks if you example was working.

        _Niklas

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

          On 30/03/2012 at 03:48, xxxxxxxx wrote:

          the example is working in c#
          http://msdn.microsoft.com/en-us/library/hyfeyz71(v=vs.80).aspx

          however, i know how to init and use arrays in c++, i also do understand the concept of new and
          its usage, but i can't get this _inline  _declaration to work. on the other hand i have to admit, that i 
          have no idea what you are talking about with

          stack-allocated array to copy it's values to a heap-allocated array if necessary

          even after some google lecture on memory and allocation. i simply didn't had to care about 
          memory in c# i guess :). in the past i was ignoring it and just used a variable, but i am curious if 
          there is a way c++ to do this, or if it is a modern language feature like c#.

          thanks for your help,

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

            On 30/03/2012 at 04:20, xxxxxxxx wrote:

            float foo (int \*myarray) 
            
            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

              On 30/03/2012 at 04:37, xxxxxxxx wrote:

              hi,

              thanks for your answer, but please consider i am a newb 😄 can you please explain what is
              meant with this pointer construction. not sure if i was conceptual unprecise, but i want to
              create/declare a variable within a call.

              foo( create here new variable defined nowhere else in the code )

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                On 30/03/2012 at 04:48, xxxxxxxx wrote:

                The pointer points at the address of the first element of an array (look up arrays and pointers in c++). If you create your array (no matter if before or in the function call) you will get that pointer that you can pass.

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                  On 30/03/2012 at 09:55, xxxxxxxx wrote:

                  You can't do that within the parantheses.

                  http://codepad.org/eTZ9drKy

                  1 Reply Last reply Reply Quote 0
                  • H
                    Helper
                    last edited by

                    THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                    On 30/03/2012 at 10:27, xxxxxxxx wrote:

                    using the new operator or a smart pointer would probably work but it really doesn't make much sense (or create a mem leak), Niklas is right. Why don't you declare it outside littledevil?

                    1 Reply Last reply Reply Quote 0
                    • H
                      Helper
                      last edited by

                      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                      On 30/03/2012 at 11:07, xxxxxxxx wrote:

                      well, i am declaring it outside right now, however i am used to this feature from c# and it is not life
                      saving important but a handy feature. i have asked this question on german speaking c++ forum too
                      and they came up with these solutions and some pages of tech gibberish :

                      1. this pointer thing samir suggested ( i still don't fully understand althought i am aware of the 
                      pointer nature of arrays).
                      2. using c++ 11
                      3. extrernal libs

                      so i am booking this under *not possible in c++*. i am often just baffled how heavy-handed c++ is 
                      compared to modern languages like c#.

                      edit : here is the link (i hope this is okay, as linking other forums sometimes is considered as a nogo)

                      http://www.c-plusplus.de/forum/301582

                      1 Reply Last reply Reply Quote 0
                      • H
                        Helper
                        last edited by

                        THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                        On 30/03/2012 at 15:47, xxxxxxxx wrote:

                        C++ doesn't have automated memory handling (i.e.: garbage collection) like some more modern programming languages.  Therefore, all memory management is in the hands of the programmer.  I know, scary! 😉

                        Pointers aren't just for arrays.  Pointers are just variable notation that stores the memory address of another variable (whether it is an array, class, or built-in type).  It is a way to pass along larger chunks of memory without passing the entire chunk through the cpu registers.

                        The problem with allocating memory in the arguments of a function/method for C++ are that there is no path to free (deallocate) that memory.  Arguments are placed on the stack (preallocated memory for the application) while allocations are typically created in the heap (general memory space available to the application).

                        Might I suggest either using Python (since it has garbage collection) or reading "Memory as a Programming Concept in C and C++" by Frantisek Franek.  The C4D Python API isn't as powerful and extensive as the C++ API currently.  The book is only a couple hundred pages but provides a very good introduction, explanation, and advantageous uses of C++ memory management.

                        1 Reply Last reply Reply Quote 0
                        • H
                          Helper
                          last edited by

                          THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                          On 31/03/2012 at 04:34, xxxxxxxx wrote:

                          Originally posted by xxxxxxxx

                          1. this pointer thing samir suggested ( i still don't fully understand althought i am aware of the pointer nature of arrays).

                          2. using c++ 11

                          3. external libs

                          1. This is the clean way to do it 🙂 And it's also super simple. Declare the array in your code before using the function, allocate it and call your function later and after you're done with the array, don't forget to free it.

                            
                          Bool foo (LONG *myarray, LONG count)   
                          {   
                          if (!myarray || count == 0) return FALSE;   
                            
                          // As an example: Fill the array with numbers   
                          LONG i;   
                          for (i = 0; i < count; i++)   
                          {   
                              myarray[i] = i*i;   
                          }   
                            
                          return TRUE;   
                          }   
                            
                          Bool PrintArray(LONG *myarray, LONG count)   
                          {   
                          if (!myarray || count == 0) return FALSE;   
                            
                          LONG i;   
                          for (i = 0; i < count; i++)   
                          {   
                              GePrint("Array[" + LongToString(i) + "] = " + LongToString(myarray[i]));   
                          }   
                            
                          return TRUE;   
                          }   
                            
                          ...   
                          ...   
                            
                          void main()   
                          {   
                          const LONG count = 100;   
                            
                          // Allocate array   
                          LONG *arr = GeAllocType(LONG, count);   
                          if (!arr)   
                          {   
                              GePrint("Error allocating the array");   
                              return;   
                          }   
                            
                          // Fill the array   
                          if (!foo(arr, count))   
                              GePrint("Filing the array didn't work out.");   
                          else   
                              GePrint("Array filled succesfully");   
                            
                          // Do something with the filled array   
                          if (!PrintArray(arr, count))   
                              GePrint("Could not print out array.");   
                            
                          // Free memory   
                          if (arr) GeFree(arr);   
                          }   
                          

                          You could also allocate the array in the same function where it's being filled with values and then return the new array:

                            
                          LONG* foo (LONG count)   
                          {   
                          if (count == 0) return NULL;   
                            
                          LONG* myarray = GeAllocType(LONG, count);   
                          if (!myarray) return NULL;   
                            
                          // As an example: Fill the array with numbers   
                          LONG i;   
                          for (i = 0; i < count; i++)   
                          {   
                              myarray[i] = i*i;   
                          }   
                            
                          return myarray;   
                          }   
                            
                          ...   
                          ...   
                            
                          void main()   
                          {   
                          const LONG count = 100;   
                            
                          // Allocate array   
                          LONG *arr = foo(count);   
                          if (!arr)   
                          {   
                              GePrint("Error allocating and filling the array");   
                              return;   
                          }   
                            
                          // Do something with the filled array   
                          if (!PrintArray(arr, count))   
                              GePrint("Could not print out array.");   
                            
                          // Free memory   
                          if (arr) GeFree(arr);   
                          }   
                          

                          2. The C4D API is currently not compatible with C++ 11 standard. Enabling C++ 11 in your compiler might lead to problems with the API code.

                          3. External libs might create extra hassle for you when compiling them for different platforms. As - quite frankly - you seem to be a beginner with C++, I would not recommend to use them.

                          Also, try to use the types defined in the C4D API (e.g. LONG instead of int), that will keep you from running into problems with 32 bit vs. 64 bit, different platforms and single precision vs. double precision.

                          1 Reply Last reply Reply Quote 0
                          • H
                            Helper
                            last edited by

                            THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                            On 31/03/2012 at 05:58, xxxxxxxx wrote:

                            hi,

                            thank you for your extensive code example, it is very much appreciated. just as a sidenote, i am
                            aware of point 2-3 and yes i am a beginner :).

                            1 Reply Last reply Reply Quote 0
                            • H
                              Helper
                              last edited by

                              THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                              On 31/03/2012 at 08:38, xxxxxxxx wrote:

                              @jack: Just a note, returning allocated memory from a function is considered bad. It's also some kind of confusing (imho).

                              -Niklas

                              1 Reply Last reply Reply Quote 0
                              • H
                                Helper
                                last edited by

                                THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                                On 31/03/2012 at 08:42, xxxxxxxx wrote:

                                Returning memory from a method is okay as long as you are cognizant that your are 'passing' ownership from the method to somewhere else so that it can be freed properly by the new owner.  The scope may be lost when returning from the method but as long as you have assigned a pointer to the new allocation that has more lasting scope, you should be okay.

                                Edit to add:

                                if (arr) GeFree(arr);

                                The conditional is not necessary.  If 'arr' is NULL then GeFree doesn't do anything (and it won't crash).  You've already checked that arr isn't NULL so it should be doubly okay.  One case to remember is that if you free memory and the execution continues you should set the pointer to it equal to NULL.   So, this is better:

                                GeFree(arr);
                                arr = NULL;  // Make sure that it doesn't point to memory that it no longer owns!

                                Any subsequent GeFree() calls (such as in a destructor) will do the appropriate thing.  Otherwise, you risk trying to free the same memory twice - and crash.

                                1 Reply Last reply Reply Quote 0
                                • H
                                  Helper
                                  last edited by

                                  THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                                  On 01/04/2012 at 03:00, xxxxxxxx wrote:

                                  Originally posted by xxxxxxxx

                                  @jack: Just a note, returning allocated memory from a function is considered bad. It's also some kind of confusing (imho).

                                  If it was considered bad, I don't think we would have any Alloc() functions in the API...

                                  BaseObject *op = BaseObject::Alloc(Onull);
                                  

                                  In fact, even the memory allocation is done by a function:

                                  LONG* myarray = GeAllocType(LONG, count);
                                  

                                  And yes, it might be confusing. But programming is a confusing thing if one does not take care 😉 Therefore, we wouldn't call this function "foo" but rather something with "Alloc".

                                  Originally posted by xxxxxxxx

                                  if (arr) GeFree(arr);The conditional is not necessary. If 'arr' is NULL then GeFree doesn't do anything (and it won't crash). You've already checked that arr isn't NULL so it should be doubly okay.

                                  Right, in this example it was obvious. But it'S better to have double and triple checks than to run into some surprising case (in more complex code) and have it crash on the user's machine.

                                  Originally posted by xxxxxxxx

                                  One case to remember is that if you free memory and the execution continues you should set the pointer to it equal to NULL.

                                  With GeFree and also with the static Free methods of the C4D API classes, that is not necessary. They set your pointer to NULL automatically (pointer reference (void*& p)). Same with the gDelete and bDelete macros.

                                  But generally, of course, one should take care to set the pointer to NULL when any other method of memory freeing is used.

                                  1 Reply Last reply Reply Quote 0
                                  • H
                                    Helper
                                    last edited by

                                    THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                                    On 01/04/2012 at 04:45, xxxxxxxx wrote:

                                    Originally posted by xxxxxxxx

                                    Originally posted by xxxxxxxx

                                    @jack: Just a note, returning allocated memory from a function is considered bad. It's also some kind of confusing (imho).

                                    If it was considered bad, I don't think we would have any Alloc() functions in the API...

                                    BaseObject *op = BaseObject::Alloc(Onull);
                                    

                                    Sorry didn't add that. We have Free() functions according to them, which is not considered bad. 🙂
                                    -Niklas

                                    1 Reply Last reply Reply Quote 0
                                    • H
                                      Helper
                                      last edited by

                                      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                                      On 02/04/2012 at 00:43, xxxxxxxx wrote:

                                      hi,

                                      i have got another question. i am still messing with my objectdata plugin. it basicly returns
                                      different geometry types based on data entered by the user (disc,plane,sphere...). as they
                                      extend some of basic capeabilities of c4ds baseobjects i thought it would be smart to
                                      outsource their allocation.

                                      currently it is something like this :

                                      BaseObject *Opolylight::GetVirtualObjects(BaseObject *op, HierarchyHelp *hh)
                                      {
                                      	...
                                      	return GetPlane(op);
                                      }
                                        
                                      static BaseObject *Opolylight::GetPlane(BaseObject *op)
                                      {
                                      	BaseObject *result = NULL;
                                      	result = BaseObject::Alloc(Oplane);
                                        
                                      	BaseContainer *outbc = result->GetDataInstance();
                                      	BaseContainer *inbc = op->GetDataInstance();
                                        
                                      	...
                                      	return result;
                                      }
                                      

                                      i am roughly following the SDK ATOM sample. but while the atom sample is just outsourcing into
                                      one other method form GetVirtualObjects, in my case it would make sense to have one method
                                      for each objecttype (GetPlane, GetDisc ...).

                                      my question is now : when the user changes the ouput from plane to disc the allocated mem from
                                      GetPlane still remains alltough it isn't used anymore. by defining the method as static i prevent
                                      the code from creating multiple instances, but my addon will still carry a bunch of data for each
                                      shape the user has choosen once.

                                      is this considered as a memory leak / bad ?

                                      1 Reply Last reply Reply Quote 0
                                      • H
                                        Helper
                                        last edited by

                                        THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                                        On 02/04/2012 at 01:48, xxxxxxxx wrote:

                                        Do you mean, the function itself still exists and redundant when not used anymore?

                                        1 Reply Last reply Reply Quote 0
                                        • H
                                          Helper
                                          last edited by

                                          THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                                          On 02/04/2012 at 01:56, xxxxxxxx wrote:

                                          the function is a pointer pointing on a baseobject, but somewhere this chain of pointer madness
                                          has to end, in my example it ends at result = BaseObject::Alloc(Oplane);. i thought it works this 
                                          way :

                                          1. GetVirtualObjects is called
                                          2. GetVirtualObjects calls GetPlane
                                          3. GetPlane allocates some memory at adress xyz and creates a BaseObject there
                                          4. GetPlane returns xyz
                                          5. GetVirtualObjects is called again
                                          6. GetVirtualObjects calls GetSphere

                                          what happens with the BaseObject @ memory adress xyz ?

                                          i guess i am geting something wrong again 😪

                                          1 Reply Last reply Reply Quote 0
                                          • H
                                            Helper
                                            last edited by

                                            THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                                            On 02/04/2012 at 02:21, xxxxxxxx wrote:

                                            In the SDK are often notes that say "Cinema 4D owns the pointed/returned object." which means Cinema will manage the memory of the object. I can't find such a note in the ObjectData::GetVirtualObjects() documentation. They either forgot to add it or you have to manage that on your own, i.e. cache the object and free it on the next call to GetVirtualObjects(). I haven't written a C++ plugin yet, (as I said, I refuse to use VC. 😉 ).

                                            Cheers,
                                            -Niklas

                                            1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post