Dynamic Arrays (One, two, three dimensions)

In summary, the author discusses how to use the equal code to deal with arrays of different dimensions and states that this code is clear to him. He also provides some code for testing the code.
  • #1
levadny
32
16
Dear Friends!

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

Code:
    // 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?
 
Technology news on Phys.org
  • #2
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.
 
  • Like
Likes levadny
  • #3
Hey levadny.

Did you want to do some test code or did you want to make functions for a library?
 
  • Like
Likes levadny
  • #4
phyzguy said:
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.
Thanks. I use this code (equal code) in my math model for diesel loco.
Below three dimensions.

Code:
    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;
 
  • #5
chiro said:
Hey levadny.

Did you want to do some test code or did you want to make functions for a library?

Is only test code. I use equal arrays in classes for datagram in UDP.
 
  • #6
Ok no worries.
 
  • #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.
 
  • #9
Irene Kaminkowa said:
If you work within the paradigm of Pure C, then new/delete is out of place.
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.
 
  • #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.
 
  • #11
levadny said:
I not use equals code in project.
What do you mean by "equals code"?
 
  • #12
Irene Kaminkowa said:
If you work within the paradigm of Pure C, then new/delete is out of place.
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.
 
  • Like
Likes Pepper Mint
  • #13
jtbell said:
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.
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.
 
  • Like
Likes Pepper Mint
  • #14
petrushkagoogol said:
The answer to this problem is to have the program allocate the memory at runtime
It was successfully done. With new

levadny, can you show us your includes? Just curious.
 
  • #15
D H said:
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,...

I think no that's not true.
23.2.6 Class template vector [vector]
A vector is a sequence container that supports random access iterators. In addition, it supports (amortized) constant time insert and erase operations at the end; insert and erase in the middle take linear time. Storage management is handled automatically, though hints can be given to improve efficiency. The elements of a vector are stored contiguously, meaning that if v is a vector where T is some type other than bool, then it obeys the identity &v[n] == &v[0] + n for all 0 <= n < v.size().
 
  • #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.
 
  • #17
Pepper Mint said:
I think no that's not true.
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:
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:
  • #18
newjerseyrunner said:
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.
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
D H said:
The elements in each row of the vector will be contiguous, but not necessarily the entire matrix.
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?
 
  • #21
D H said:
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:
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.
Yes and I think it is logical. Each row in the loop is resized or defined differently at the memory level. I think you can either use boost's multi-array or transform your 2D array into 1D vector to assign contiguous blocks of memory for all of its members.
 
  • #22
For contiguous memory:

Code:
    int **arr2 = new int *[X];
    arr2[0] = new int[X*Y];
    for(int i = 1; i < X; i++)
        arr2[i] = arr2[i-1] + Y;
    // ...
    delete[] arr2[0];
    delete[] arr;
 
Last edited:
  • #23
According to the sacred book ;) dereferenced pointers are recommended instead of array substript, that is
*(*(*(A + i) + j)+k) instead of A [i ][j ][k ]

As for transformation of a 3D array into 1D, the rule is simple
Assume d1,d2,d3 - dimensions
Then
A[i ][j ][k ] = A_line [k + d3⋅(j + d2⋅i)]
 

What is a dynamic array?

A dynamic array is a data structure that allows for the storage of a variable number of elements. Unlike traditional arrays, which have a fixed size, dynamic arrays can grow or shrink in size as needed.

How are dynamic arrays different from traditional arrays?

Traditional arrays have a fixed size that must be specified when the array is created. This means that the size cannot be changed during program execution. Dynamic arrays, on the other hand, can be resized as needed, making them more flexible for handling varying amounts of data.

What are the advantages of using dynamic arrays?

Dynamic arrays offer several advantages, including the ability to store a variable number of elements, efficient memory usage, and the ability to easily add or remove elements from the array without having to create a new array.

How are dynamic arrays implemented?

Dynamic arrays are typically implemented using pointers and memory allocation. When the array needs to grow, a larger block of memory is allocated and the elements are copied over. When the array needs to shrink, the unused memory is deallocated.

What are the limitations of dynamic arrays?

One limitation of dynamic arrays is that they require more memory than traditional arrays, as they may need to allocate extra memory for future growth. Additionally, dynamic arrays may also suffer from performance issues when elements are added or removed frequently, as this requires memory reallocation and copying of elements.

Similar threads

  • Programming and Computer Science
Replies
4
Views
3K
  • Programming and Computer Science
Replies
25
Views
2K
  • Programming and Computer Science
Replies
9
Views
1K
  • Programming and Computer Science
Replies
17
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
3
Views
755
  • Programming and Computer Science
Replies
17
Views
1K
  • Programming and Computer Science
Replies
23
Views
1K
  • Programming and Computer Science
Replies
20
Views
1K
  • Programming and Computer Science
Replies
3
Views
1K
  • Programming and Computer Science
Replies
1
Views
946
Back
Top