Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

C/++/# Dynamic Arrays (One, two, three dimensions)

  1. Jul 12, 2016 #1
    Dear Friends!

    My post about dinamic arrays. For example little bit code.

    Code (C):
        // size
        int const X = 5;
        int const Y = 4;
        int const Z = 3;

        // one dimension array
        printf("\nOne dimension\n");
        // array of pointers
        int * Arr;
        // create array
        Arr = new int [X];
        // work with array
        for(int i = 0; i < X; i++)
            Arr[i] = (i + 1);
        // print array
        for(int i = 0; i < X; i++)
            printf("Arr[%d] = %d\n", i, Arr[i]);
        // remove array
        delete[] Arr;
        printf("\n");

        // Two dimensions
        printf("\nTwo dimensions\n");
        // array of pointers
        int **Arr2;
        // create "strings"
        Arr2 = new int*[X];
        // create colomns
        for(int i = 0; i < X; i++)
            Arr2[i] = new int[Y];
        // work with array
        for(int i = 0; i < X; i++)
            for(int j = 0; j < Y; j++)
                Arr2[i][j] = 10 * (i + 1) + (j + 1);
        // print
        for(int i = 0; i < X; i++)
        {
            for(int j = 0; j < Y; j++)
                printf("%d\t", Arr2[i][j]);
            printf("\n");
        }
        // remove
        for(int i = 0; i < X; i++)
            delete[] Arr2[i];
        delete[] Arr2;
    Question. I not use equals code in project. This code is work, no problem.
    Do you think this is a literate code?
    It is clear?
     
  2. jcsd
  3. Jul 12, 2016 #2

    phyzguy

    User Avatar
    Science Advisor

    This code is clear to me. I think this is a perfectly reasonable way to deal with multi-dimensional arrays. There are other ways, but this is quite acceptable in my opinion.
     
  4. Jul 13, 2016 #3

    chiro

    User Avatar
    Science Advisor

    Hey levadny.

    Did you want to do some test code or did you want to make functions for a library?
     
  5. Jul 13, 2016 #4
    Thanks. I use this code (equal code) in my math model for diesel loco.
    Below three dimensions.

    Code (C):

        printf("\nThree demensions\n");
        // array of pointer
        int ***Arr3;
        // create "strings"
        Arr3 = new int**[X];
        // create colomns
        for(int i = 0; i < X; i++)
            Arr3[i] = new int *[Y];
        // create z-dimension
        for(int i = 0; i < X; i++)
            for(int j = 0; j < Y; j++)
                Arr3[i][j] = new int[Z];
        // work with array
        for(int i = 0; i < X; i++)
            for(int j = 0; j < Y; j++)
                for(int k = 0; k < Z; k++)
                    Arr3[i][j][k] = 100 * (i + 1) + 10 * (j + 1) + (k + 1);
        // print
        for(int i = 0; i < X; i++)
        {
            for(int j = 0; j < Y; j++)
            {
                printf("(");
                for(int k = 0; k < Z; k++)
                    printf("%d,", Arr3[i][j][k]);
                printf("\b)\t");
            }
            printf("\n");
        }
        // remove
        for(int i = 0; i < X; i++)
            for(int j = 0; j < Y; j++)
                    delete[] Arr3[i][j];
        for(int i = 0; i < X; i++)
                delete[] Arr3[i];
        delete[] Arr3;
     
  6. Jul 13, 2016 #5
    Is only test code. I use equal arrays in classes for datagram in UDP.
     
  7. Jul 13, 2016 #6

    chiro

    User Avatar
    Science Advisor

    Ok no worries.
     
  8. Jul 14, 2016 #7
  9. Jul 14, 2016 #8
    https://en.wikibooks.org/wiki/A_Little_C_Primer/C_Dynamic_Memory_Allocation_&_Deallocation

    For simple programs, it is OK to just declare an array of a given size:

    char buffer[1024]

    In more sophisticated programs, this leads to trouble. There may be no way of knowing how big an array needs to be for the specific task the program is performing, and so allocating an array in a fixed size will either result in wasted memory or in not having enough to do the job.

    The answer to this problem is to have the program allocate the memory at runtime, and that's what the "malloc()" library function does.
     
  10. Jul 14, 2016 #9

    jtbell

    User Avatar

    Staff: Mentor

    And if you're really working in C++, you should consider using vectors instead of dynamic arrays. The equivalent of a two-dimensional dynamic array would be a vector of vectors. In that case you don't use new/delete (or malloc/free) yourself. The vector member functions do that for you.
     
  11. Jul 14, 2016 #10
    No, I would recommend making your own class which uses vectors. a vector of vectors is not the same as a 2D array. I 2D array implies to me that all buckets in it are the same size. If you use a vector, every time you add something, only the bucket you add to will expand. You'll get all these weird mismatched lengths of buckets that look nothing like a 2D array.
     
  12. Jul 14, 2016 #11

    jtbell

    User Avatar

    Staff: Mentor

    What do you mean by "equals code"?
     
  13. Jul 14, 2016 #12

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    Since the OP is using new and delete, it's better to assume the OP is using C++.

    That said, the OP's use of new and delete are out of place in modern C++. There is no reason to use new and delete in this fashion. This is just malloc and free, disguised. Much better is to use the fact that in C++ one can define classes. The modern approach is to use the terribly named concept of RAII ("Resource Allocation Is Initialization"). What this means is that, for example, a 2D matrix class should handle the allocation and deallocation of resources internally. Users of that class do not need to call new or delete, period.
     
  14. Jul 14, 2016 #13

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    A vector of vectors (or an std::array of std::arrays) generally is not a good approach in the context of scientific programming. The allocated data are dispersed across memory, and that means that you'll get lots of cache misses when, for example, calculating the product of a matrix and a vector. It's much better to use a contiguous sequence of memory, where some_2d_array[i,j] is calculated as some_2d_array.data[i*M+j]. The cost of that integer multiplication and one memory lookup in cache memory is very small compared to the cost of two memory lookups with data that aren't in cache memory.
     
  15. Jul 14, 2016 #14
    It was successfully done. With new

    levadny, can you show us your includes? Just curious.
     
  16. Jul 14, 2016 #15
    I think no that's not true.
     
  17. Jul 14, 2016 #16
    Just thought I'd mention a weird quirk of C++. new is much much much slower than malloc. new aligns memory, malloc does not. For POD, malloc is usually preferred over new. It also then allows to you realloc, which you can not do with new.
     
  18. Jul 14, 2016 #17

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    It is quite true.

    While the memory for a single std::vector is contiguous, there's nothing in the standard (or in any implementation I know of) that guarantees that for a vector of vectors. Here's a vector of vectors:
    Code (C):
    std::size_t N, M; // Number of rows and columns in the array.
    ...
    std::vector<std::vector<double>> vector_of_vectors;
    vector_of_vectors.resize(N);
    for (std::size_t i = 0; ii < N; ++ii) {
        vector_of_vectors[ii].resize(M);
    }
    The elements in each row of the vector will be contiguous, but not necessarily the entire matrix. My experience is that typically the entire matrix is not contiguous.
     
    Last edited: Jul 14, 2016
  19. Jul 14, 2016 #18

    D H

    User Avatar
    Staff Emeritus
    Science Advisor

    What version of C do you use? On every system I have used, malloc has always returned a pointer that "is suitably aligned so that it may be assigned to a pointer to any type of object with a fundamental alignment requirement ..." That specific phrase has been in the C standard since 1999. I don't have a copy of the first version of the C standard; it might well have been there as well. In any case, in every version of C I've used since the early 90s, malloc has returned a pointer aligned to the largest possible boundary. For example, malloc(1) will give a pointer that is aligned to a 64 byte boundary on most modern systems (128 bytes on some), and the next call to malloc(1) will not poke into the 64 (or 128) bytes that actually were allocated for the first call to malloc(1).

    I've yet to work on a system where malloc and new exhibited any speed difference for POD. I have worked at multiple organizations that told people in code reviews of C++ code to change their calls to malloc to new. They raised your objection, and then they tested to see if the new code using new was slower. No observable speed difference was observed. Any halfway respectable optimizing compiler will optimize new SomePodType to malloc(sizeof SomePodType).
     
  20. Jul 15, 2016 #19
  21. Jul 15, 2016 #20

    jtbell

    User Avatar

    Staff: Mentor

    The OP's code uses separate calls to 'new' for each column of the matrix (allocating column-wise instead of row-wise). Those wouldn't necessarily be contiguous either, right?
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?
Draft saved Draft deleted



Similar Discussions: Dynamic Arrays (One, two, three dimensions)
  1. Two char arrays (Replies: 11)

Loading...