logo elektroda
logo elektroda
X
logo elektroda
Dostępna jest polska wersja

Czy wolisz polską wersję strony elektroda?

Nie, dziękuję Przekieruj mnie tam

[C++] Creating a Two-Dimensional Dynamic Array vs Static Array: Elements, Usage, & Syntax

malum 30947 28
Best answers

Why is `int tab[w][k]` not a valid dynamic two-dimensional array in C++, and how should I create a dynamic 2D array instead?

`int tab[w][k]` is not standard C++; it is a variable-length array extension that some compilers like Dev-C++/GCC accept, but ISO C++ forbids it [#7223281][#7234283] The portable way is to allocate dynamically, for example `int* tab = new int[size];` for one dimension, or for 2D use one contiguous block such as `int* tabDyn = new int[w * k];` and access elements with `tabDyn[i * number_columns + j]` [#7225184][#7235492] `int** tab` is not a true 2D array; it is an array of pointers to separate 1D arrays [#7222775] A pointer-based 2D layout can still be indexed as `tab[i][j]`, but it is built from multiple allocations and is different from a single contiguous `w*k` array [#7222775][#7235492] The thread also notes that the VLA form uses stack memory, so it is limited by stack size, while `new` allocations come from the heap [#7234283][#7237172]
Generated by the language model.
ADVERTISEMENT
Treść została przetłumaczona polish » english Zobacz oryginalną wersję tematu
  • #1 7221669
    malum
    Level 23  
    Hello!
    I am wondering how to create a dynamic array in C ++
    According to all the descriptions I've found, we create a two-dimensional array like this:

    
      int w=10, k=10;
      int **tab = new int *[w];
      for ( int i = 0; i < w; ++i )
         tab[i] = new int [k];
    


    what prevents declaring such a table like this:

    
    int w=10, k=10;
    int tab[w][k];  
    


    Both versions work theoretically the same, while the second version is incomparably simpler and more natural.
  • ADVERTISEMENT
  • #2 7222688
    marihires
    Level 30  
    That second code not presents the blackboard dynamic .
    Theoretically, they don't work the same :) .
    Greetings.
  • #3 7222775
    jestam
    Automation specialist
    int ** tab to not is a two-dimensional array. It is a one-dimensional array of pointers that point to one-dimensional int arrays.

    you allocate an array of pointers to an int counting in elements:
    int ** tab = new int * [w];

    then in the loop you allocate k elements each in int arrays and assign their addresses to the elements of the tab array:

    for (int i = 0; i
  • #4 7222923
    Dr.Vee
    VIP Meritorious for electroda.pl
    malum wrote:
    what prevents declaring such a table like this:

    
    int w=10, k=10;
    int tab[w][k];  
    


    The array would be dynamic if it could be declared like this:
    
    extern unsigned w;
    extern unsigned h;
    
    int tab[w][h];


    Maybe try compiling the code you post on the forum first? :)

    Greetings,
    Dr. Vee
  • #5 7222975
    malum
    Level 23  
    Dr.Vee wrote:
    Maybe try compiling the code you post on the forum first? :)
    Greetings,
    Dr. Vee


    Oh, I think the dear moderator did not read something ...
    So here you go, the code of the sample program:

    [code:1:658e058098]
    #include
    using namespace std;

    int main()
    {
    int a,b,lp=0;
    cout > a;
    cout > b;
    cout
    Attachments:
    • tablica.exe (572.06 KB) You must be logged in to download this attachment.
    • tablica.cpp (575 Bytes) You must be logged in to download this attachment.
  • #6 7223281
    Dr.Vee
    VIP Meritorious for electroda.pl
    Your compiler can do such things optional support (mine also supports), but it doesn't change the fact that ISO C ++ doesn't allow this behavior:
    g++ -Wall -pedantic    tablica.cpp   -o tablica
    tablica.cpp: In function `int main()':
    tablica.cpp:13: error: ISO C++ forbids variable-size array `tab'

    The same for global variables (example from extern) and for class attributes ...

    Either way, it's best to use a suitable abstraction, e.g. your own class / pattern or stl :: vector. Regular arrays (especially dynamic ones) generate too many potential errors.

    Greetings,
    Dr. Vee
  • #7 7224294
    malum
    Level 23  
    Dr.Vee wrote:
    Your compiler can do such things optional support (mine also supports), but it doesn't change the fact that ISO C ++ doesn't allow this behavior:
    g++ -Wall -pedantic    tablica.cpp   -o tablica
    tablica.cpp: In function `int main()':
    tablica.cpp:13: error: ISO C++ forbids variable-size array `tab'

    The same for global variables (example from extern) and for class attributes ...

    Either way, it's best to use a suitable abstraction, e.g. your own class / pattern or stl :: vector. Regular arrays (especially dynamic ones) generate too many potential errors.

    Greetings,
    Dr. Vee


    Therefore, I can ask for an example program with dynamic arrays, because when I enter "c ++ dynamic arrays" in google, the only thing that shows me is the version with pointers, which, according to the previous speaker, are not arrays, and he is right, but in I still don't know how to build a valid one- and two-dimensional dynamic arrays :(
  • #8 7224816
    several
    Level 15  
    In the second case, you will have to declare the values of wih variables in the program, you will not be able to assign their values using cin, for example.

    The "version with pointers" consists in allocating a suitable amount of memory to yourself first, and then declaring a specific size of the array. You do it when at the stage of code creation you do not know what size of the array you will need or this size will change.

    And if you want an example, let's say you want to do some graphics operations, it's clear that you don't want to wonder what size this graphic is and whether you need to change the code to load it, you want it to load regardless of size, then you create a dynamic array. according to the first method.
  • ADVERTISEMENT
  • #9 7225064
    malum
    Level 23  
    several wrote:
    In the second case, you will have to declare the values of wih variables in the program, you will not be able to assign their values using cin, for example.

    The "version with pointers" consists in allocating a suitable amount of memory to yourself first, and then declaring a specific size of the array. You do it when at the stage of code creation you do not know what size of the array you will need or this size will change.

    And if you want an example, let's say you want to do some graphics operations, it's clear that you don't want to wonder what size this graphic is and whether you need to change the code to load it, you want it to load regardless of size, then you create a dynamic array. according to the first method.


    I can declare size in cinem, because even above I have included a working program.
    You write that I am supposed to create a dynamic array as per the first example, but this is not a dynamic array, but an array of pointers, and it works exactly like the second example. Maybe it's not beautifully written formally, but it works - DevC ++ compiles this code flawlessly!
    As for the examples, I would prefer something based on a code, and not a theoretical example, because theoretically I know what a dynamic variable is, but in practice I cannot find such a variable anywhere. If you have any code, post it on the forum, it will probably be useful to many electrodes.
  • #10 7225184
    jestam
    Automation specialist
    Quote:

    Therefore, I can ask for an example program with dynamic arrays, because when I enter "c ++ dynamic arrays" in google, the only thing that shows me is the version with pointers, which, according to the previous speaker, are not arrays, and he is right, but in I still don't know how to build a valid one- and two-dimensional dynamic arrays


    One-dimensional dynamic array: int * tab = new int [size];

    Two-dimensional and more-dimensional tables are quite specific. For example, int tab2 [2] [3] is 2 * 3 = 6 consecutive ints. If you want to refer to the element tab2 [i] [j] then the compiler computes [i * 3 + j] and refers to this element.

    How to do it dynamically:
    [code:1:5c21db60c5]
    int* tabDyn = new int [w * k];
    int lp = 0;
    for(int i=0;i
  • #11 7225227
    malum
    Level 23  
    jestam wrote:

    One-dimensional dynamic array: int * tab = new int [size];


    Isn't that making your life difficult, since the classic int tab [size] also works; where [size] can be specified anywhere in the program as needed? The effect is exactly the same as int * tab = new int [size]; only easier to write. Maybe, as Dr. Vee mentioned, maybe it is not compatible with ISO C ++, but since it works and the compilers can handle it, maybe the language is just developing and "time for changes ..."

    However, I am interested in only one thing, and this is probably the only difference for me, or I do not know something - how to slow down my memory? An array created with new is removed with the delete command, and what about the other type of array? Is there any way to free memory?
  • #13 7225429
    malum
    Level 23  
    marihires wrote:
    I will direct you to read about static and dynamic tables:

    Link1
    Link2
    Link3

    After reading this, what differences do you see in these records:

    int * tab = new int[rozmiar];


    int tab[rozmiar]


    :?:

    Greetings.


    I read it, but I don't quite understand what you are getting at.
    I know how to create dynamic arrays int * tab = new int [size]; because I have been doing this myself for years, but I was surprised how, by accidentally playing around with variables, I used the notation int tab [size]; and the program worked as well.
    I am interested in strong arguments against the second, shorter version, which also works. One of the arguments may be freeing memory, but ... and hence my question, is there any way to free memory in the simpler example?
    The pages you sent me did not bring anything new.
  • ADVERTISEMENT
  • #14 7227314
    several
    Level 15  
    malum wrote:


    I can declare size in cin, because even above I have included a working program. [...]
    Maybe it's not beautifully written formally, but it works - DevC ++ compiles this code flawlessly!


    One compiler will accept it and another will not. The following code:
    [code:1:6f45694815]
    int w, h;
    cout
  • #15 7227381
    malum
    Level 23  
    several wrote:
    malum wrote:


    I can declare size in cin, because even above I have included a working program. [...]
    Maybe it's not beautifully written formally, but it works - DevC ++ compiles this code flawlessly!


    One compiler will accept it and another will not. The following code:
    [code:1:c1495204e7]
    int w, h;
    cout
  • #16 7227457
    several
    Level 15  
    malum wrote:

    The program is compiled in DevC ++ without any problems. I realize that many compilers can't handle this


    IMHO it is not a question of whether the compiler can handle it or not, but whether the writing is correct. Dev hasn't been updated in ages, no current compiler should accept this entry. If at the stage of code creation you do not know what size of the array you will need, you implement dynamic arrays, if you know exactly what size the array should be, you use arrays of constant size. In my opinion, there is no point in discussing this issue too much.
  • #17 7227506
    malum
    Level 23  
    several wrote:
    malum wrote:

    In DevC ++ the program is compiled without any problems. I realize that many compilers can't handle it


    IMHO it is not a question of whether the compiler can handle it or not, but whether the writing is correct. Dev hasn't been updated in ages, no current compiler should accept this entry. If at the stage of code creation you do not know what size of the array you will need, you implement dynamic arrays, if you know exactly what size the array should be, you use arrays of constant size. In my opinion, there is no point in discussing this issue too much.


    But why?
    Why can't I determine the size of the array after running the program? Give logical arguments. You are right that DevC ++ has not been updated, but it compiles, and the updated ones have not ... Maybe they defend themselves against this kind of treatment. German car manufacturers until recently denied the use of direct injection displays, and now they use it, Nikon denied that it would never make a full-size SLR camera, and maybe it's time for programmers ... Why make your life difficult?
  • #18 7227943
    several
    Level 15  
    malum wrote:

    Why can't I determine the size of the array after running the program?

    How can you! Only then do you need to implement a dynamic array in your code ;)
  • #19 7232439
    malum
    Level 23  
    several wrote:
    malum wrote:

    Why can't I determine the size of the array after running the program?

    How can you! Only then do you need to implement a dynamic array in your code ;)


    In my example with DevC ++ you can too, so everything is fine :-)
  • ADVERTISEMENT
  • #20 7232924
    jestam
    Automation specialist
    malum wrote:

    Maybe they defend themselves as much as possible against this kind of treatment


    Don't look for conspiracies ;)

    Use the debugger and see what code is generated for int tab [h] [w];
    Compare with the code generated for int tab [2] [3] and new int [2 * 3] and draw your conclusions.
  • #21 7234283
    Dr.Vee
    VIP Meritorious for electroda.pl
    Code provided by a colleague malum compiles, because DevC ++ "under the hood" uses MinGW, or GCC. GCC supports the ISO C99 standard that allows such declarations (this is called VLA = Variable Length Array). Since the C ++ compiler in GCC (i.e. g ++) uses the same code generator, VLAs are also supported in C ++, although in fact they are not part of the standard.

    In GCC, the VLAs are allocated on the stack (although this is not a VLA requirement). This is a significant difference as the memory for the arrays allocated by new comes from the heap by default.

    Greetings,
    Dr. Vee
  • #22 7235093
    malum
    Level 23  
    jestam wrote:

    Don't look for conspiracies ;)


    I'm not looking for :-)
    I'm just wondering about the definition of the dynamic array and trying to port it to C ++. So far, I do not feel convinced that the design
     int * tab = new int[rozmiar];
    it's a dynamic array, and you corrected me at the very beginning that it's not an array but pointers. A real dynamic array is a normal array that can be sized at runtime, that is
     int tab[rozmiar] 
    Since DevC ++ compiles such a structure, it works 100% correctly, it is much easier to use, especially when using multidimensional arrays, why not use it? Maybe the problem is not DevC ++ or another compiler, but simply the reluctance of programmers to change? When you show a 70-year-old computer, he will wince, but when he learns to leave, he does not want to leave. According to me, all software producers should switch to such a way of declaring dynamic tables, it is easier, faster and more intuitive. You don't have to browse through dozens of pages or books to create a dynamic array, you just need to know what a regular array looks like. What's more, having such a structure of a dynamic array, we can "stop" using standard arrays, and why, since we can declare its size just before using it. I would like to find out from you what are the disadvantages of such a solution, but specifically, e.g. 20% more memory consumption, 40% reduced program performance, etc. because these would actually be arguments against, but since they are not there ...
  • #23 7235465
    several
    Level 15  
    malum wrote:
    Since DevC ++ compiles such a structure [...]

    It compiles because it's old and out of date. If you base your arguments only on this "because DevC ++ compiles" then your argumentation is very poor. If you want to write like this, write, but be aware that the vast majority of IDE will not accept such syntax, and certainly no one is updated and developed on an ongoing basis. When C ++ becomes a tool for you and not a target, you will agree with me ;)
    malum wrote:

    Maybe the problem is not DevC ++ or another compiler, but simply the reluctance of programmers to change?

    Oh man, you swam over the edge, I almost fell off my chair :D But I'll tell you that you are partially right, but the only "programmer" who has any reluctance to change is you ;) Re-read the posts of colleagues smarter than you (and me too) before you write anything else.
  • #24 7235492
    jestam
    Automation specialist
    
    int * tab = new int[rozmiar];
    

    is dynamic, one-dimensional array int. In C / C ++, the name of an array is a pointer to its first element, and the [] brackets can be used with any pointer:
    
    int tab[10];
    int * wsk = tab;
    wsk[2] = 5;
    


    A problem arises with dynamic multidimensional arrays, which can be created as an array of pointers (to arrays of pointers) to one-dimensional arrays and use the syntax tab_dyn [i] [j] or create them as a contiguous memory area of tab_dyn [i * j] and refer to the cells with tab_dyn [i * number_columns + j].

    Quote:

    I would like to find out from you what are the disadvantages of such a solution

    Dr. Vee gave two potential drawbacks (emphasis mine):
    Dr.Vee wrote:

    GCC supports the ISO C99 standard that allows such declarations (this is called VLA = Variable Length Array). Since the C ++ compiler in GCC (i.e. g ++) uses the same code generator, VLAs are also supported in C ++, although they are in fact not part of the standard .

    Just in the GCC VLA are allocated on the stake (though not a VLA requirement). This is a significant difference as the memory for arrays allocated by new comes by default from the heap


    Lack of code portability and limited stack space.
  • #25 7235771
    malum
    Level 23  
    jestam wrote:

    Lack of code portability and limited stack space.


    As for the portability of the code, I reject this argument, because it is contrary to the evolution of the program - just let the authors of programs that do not support such a structure add it.
    I am willing to accept the second argument, but I am interested in the exact data. How am I to understand heaps are endless and heaps ... yeah, what's the upper limit?
  • #26 7237172
    jestam
    Automation specialist
    Quote:

    As for the portability of the code, I reject this argument, because it is contrary to the evolution of the program - just let the authors of programs that do not support such a structure add it.


    When you write "program", do you mean "compiler"? The lack of code portability is not an argument, it is a fact. If irrelevant to you - your right.

    Quote:

    How am I to understand heaps are endless and heaps ... yeah, what's the upper limit?


    Google! There are no limitless things in computer science. The heap size is limited by physical memory and swap file space.

    http://msdn.microsoft.com/en-us/library/ms686774 (VS.85) .aspx " target="_blank" rel="nofollow noopener ugc" class="postlink inline" title="" > http://msdn.microsoft.com/en-us/library/ms686774 (VS.85) .aspx : "The default stack reservation size used by the linker is 1 MB"
    http://blogs.technet.com/markrussinovich/archive/2009/07/08/3261309.aspx " target="_blank" rel="nofollow noopener ugc" class="postlink inline" title="" > http://blogs.technet.com/markrussinovich/archive/2009/07/08/3261309.aspx
  • #27 7237194
    malum
    Level 23  
    [quote = "I am"]
    Quote:

    There are no limitless things in computer science. The heap size is limited by physical memory and swap file space.


    Well, also the argument of little value, since both the pile and the heap have their limit
  • #28 7238899
    jestam
    Automation specialist
    Maybe read a bit, at least from the links I have provided. Consider where the limit of the heap capacity is, and where is the stack, and what each one is used for.
  • #29 7239242
    malum
    Level 23  
    jestam wrote:
    Maybe read a bit, at least from the links I have provided. Consider where the limit of the heap capacity is, and where is the stack, and what each one is used for.


    Pictures are nice, unfortunately the rest are not in Polish, so maybe a short summary in the mother tongue?

Topic summary

✨ The discussion revolves around the creation of two-dimensional dynamic arrays versus static arrays in C++. The main question highlights the user's confusion regarding the differences between using pointers to create dynamic arrays and declaring static arrays with fixed sizes. Responses clarify that a dynamic array created with pointers (e.g., `int **tab = new int *[w];`) is fundamentally different from a static array (e.g., `int tab[w][k];`), as the former allows for dynamic memory allocation at runtime, while the latter requires fixed sizes known at compile time. The conversation also touches on the limitations of variable-length arrays (VLAs) in C++ and the importance of memory management, emphasizing that dynamic arrays must be deallocated using `delete`, whereas static arrays are automatically managed. The participants debate the practicality and portability of different array types, with some advocating for the use of STL containers like `std::vector` for better memory management and flexibility.
Generated by the language model.

FAQ

TL;DR: 1 MB default Windows stack limit means a 500×500 int VLA (≈1 MB) can crash quickly; "ISO C++ forbids variable-size array" [Elektroda, Dr.Vee, post #7223281] Use heap-based new[] or std::vector for portable, resize-able 2-D storage. GCC compiles VLAs only as a non-standard extension.

Why it matters: Choosing the right allocation method prevents hard-to-debug crashes and non-portable code, especially in memory-hungry embedded or graphics work.

Quick Facts

• ISO C++ 17 and 20 exclude Variable Length Arrays (VLAs) — only fixed-size, heap or STL containers are standard [ISO C++, 2017]. • GCC allocates C-style VLAs on the stack, not the heap [Elektroda, Dr.Vee, post #7234283] • Windows executable’s default thread stack is 1 MB; linkers allow custom sizes [Microsoft Docs, 2023]. • std::vector grows capacity by roughly 2×, giving amortised O(1) push_back [cppreference, 2023]. • Deleting a pointer-of-pointers 2-D array needs w calls to delete[] plus one final delete[] for the row list [Elektroda, jestam, post #7222775]

What’s the real difference between `int **tab` and `int tab[w][k]`?

int **tab is one heap block of w pointers; each pointer references a separate int[k] block. int tab[w][k] is a single contiguous region of w × k integers determined at compile time. The first form offers per-row allocation but costs extra indirection; the second has faster cache access but fixed size [Elektroda, jestam, post #7222775]

Is `int tab[w][k]` a dynamic array in standard C++?

No. Standard C++ requires the dimensions be compile-time constants. A runtime dimension makes it a Variable Length Array, which ISO C++ forbids [Elektroda, Dr.Vee, post #7223281] Compilers like GCC accept it only as an extension, so the code is non-portable.

Why does GCC compile VLAs but MSVC rejects them?

GCC reuses its C99 front-end that legally supports VLAs, so the feature leaks into C++. MSVC follows the ISO C++ spec strictly and flags a variable-size array as an error. Hence code relying on VLAs builds on GCC/Clang but not on MSVC [Elektroda, Dr.Vee, post #7234283]

How much memory does a 1000×1000 `int` VLA use, and can it fail?

A 1000×1000 int array needs about 4 MB (1 000 000 × 4 bytes). Placed on a 1 MB default stack, it triggers stack overflow immediately. Heap or std::vector avoids this failure [Microsoft Docs, 2023].

What’s the safest modern C++ way to build a runtime-sized 2-D array?

Use a single std::vector<int> sized to rows*cols, or std::vector<std::vector<int>> if jagged rows help. Both manage memory automatically and are fully standard, portable, and exception-safe [cppreference, 2023].

How do I free memory from a pointer-of-pointers 2-D array?

Loop through each row, call delete[] row;, then delete[] tab;. Skipping either call leaks memory or double-deletes [Elektroda, jestam, post #7222775]

Can I resize a Variable Length Array after creation?

No. A VLA’s size is fixed once execution passes its declaration. To resize, allocate on the heap with new[] or use std::vector::resize() [ISO C++, 2017].

How do I iterate a flat `std::vector` that stores a matrix?

Index element (r,c) as vec[r*cols + c]. This arithmetic matches what compilers do for static 2-D arrays, so it stays cache-friendly [Elektroda, jestam, post #7225184]

Edge case: what happens if I keep pushing large VLAs inside a recursive function?

Each recursion level adds a VLA to the stack. Deep recursion plus large VLAs exhaust stack space fast, causing a stack overflow exception or program abort—a classic hidden bug [Microsoft Docs, 2023].

Which mainstream compilers still allow VLAs in C++?

GCC and Clang enable them by default; you can disable with -Wvla or -pedantic. MSVC, Intel C++ and Borland reject them as errors [GCC Docs, 2023].

Are VLAs slower than heap arrays?

Access speed is similar, but heap arrays incur one allocation overhead, while VLA creation just moves the stack pointer. However, VLAs risk stack overflow and remain non-portable, outweighing the micro-optimisation [Elektroda, Dr.Vee, post #7234283] "Portability beats micro-optimisation every time." [Elektroda, jestam, post #7237172]

Quick how-to: create and release a heap 2-D array in three steps.

  1. Allocate row list: int **tab = new int*[rows];
  2. For each i, allocate row: tab[i] = new int[cols];
  3. Cleanup: for(int i=0;i<rows;++i) delete[] tab[i]; delete[] tab; [Elektroda, jestam, post #7222775]
Generated by the language model.
ADVERTISEMENT