Dynamically Allocate A 2D Array | C Programming Tutorial

Поділитися
Вставка
  • Опубліковано 14 жов 2024
  • How to dynamically allocate a 2D array using C. Source code: github.com/por.... Check out www.portfolioc... to build a portfolio that will impress employers!

КОМЕНТАРІ • 68

  • @salomonchambi
    @salomonchambi 2 роки тому +27

    What a clear and straightforward explanation! thanks for your time Kevin!

  • @TL-fe9si
    @TL-fe9si 2 роки тому +10

    one can also use int (*array)[5] = malloc(5 * 5 * sizeof(int)); to directly allocate a block of memory for 2d array of size 5 * 5 on the heap segment. If we do it this way, the allocated memory block is consecutive with respect to the program's address space. If we use the double-pointer method shown in this video, the address of pointers in the 1st dimension of the array is consecutive, and the memory address of elements in each row is consecutive, but the address of different rows may not form a consecutive block in the program's address space.

    • @PortfolioCourses
      @PortfolioCourses  2 роки тому +3

      That's true! :-) There are multiple ways we can dynamically allocated a 2D array, people that are interested in learning more about this may find these links helpful:
      www.techiedelight.com/dynamically-allocate-memory-for-2d-array/
      www.geeksforgeeks.org/dynamically-allocate-2d-array-c/

    • @ronald3836
      @ronald3836 Місяць тому

      And recently I realized that, at least in C, you can allocate them to have a dynamical size:
      int n = f(0), m = f(1); // calculate values of n and m at runtime
      int (*array)[n][m] = malloc(sizeof(*array));
      Now the array can be accessed as (*array)[i][j].
      Alternatively:
      int (*array)[m] = malloc(n * sizeof(*array));
      Now the array can be accessed as array[i][j].

  • @D.Wapher
    @D.Wapher Рік тому +3

    Thanks for the in depth explanation of the whole process, respect.

  • @Devva03
    @Devva03 8 днів тому

    This is literally God's work that you're doing for newbies, Mister!!

  • @hotpil7020
    @hotpil7020 2 роки тому +33

    Don't forget that to free the array correctly. Doing free(array) is wrong! Because it deallocates only the array of pointers to arrays. The arrays themselfs are now unaccessible and you will have a memory leakage. The correct way is first to deallocate each array, i.e. do for (i=0;i

  • @Brock-Landers
    @Brock-Landers 2 роки тому +2

    In my limited experience, most of the time only the first dimension of a dynamic 2D int array needs to change. That being the case, memory management is much easier when you use a pointer to array of integers instead of a pointer to a pointer of ints.
    #define DIM2 5
    {
    int i;
    int array_count = 5;
    int (*array)[DIM2];
    int (*temp)[DIM2]
    array = malloc((array_count * DIM2) * sizeof(int)); /* one call */
    /* do work with 5 int arrays */
    temp = realloc(array, ((array_count + 5) * DIM2) * sizeof(int));
    array = temp;
    /* do more work with 5 more int arrays */
    free(array) /* everything free in one call */
    }

    • @PortfolioCourses
      @PortfolioCourses  2 роки тому +1

      Thanks for sharing this! 🙂 That's definitely a nice way to handle it if you don't need to change the one dimension, and I agree it's often the case we only need to change the one dimension. I've also seen people just declare a massive "1D" block of memory and use it as a "2D array" by using indexes like array[row * total_columns + column].

    • @Brock-Landers
      @Brock-Landers 2 роки тому

      @@PortfolioCourses I didn't think of it before, because I always code C in the c89 standard, but you can use a variable length array on the second dimension when using c99 or later and still only need the one allocation and one free. I'm stuck in the 80s, and wish I go back. We didn't have massive blocks back then...

  • @yogeshchauhan9401
    @yogeshchauhan9401 Рік тому +1

    Wow what a explanation 😲 was stuck in a question but now its clear 🎉

    • @PortfolioCourses
      @PortfolioCourses  Рік тому

      I'm really glad to hear you enjoyed the explanation and that it made things clear! :-)

    • @yogeshchauhan9401
      @yogeshchauhan9401 Рік тому

      @@PortfolioCourses one question,do we have to type cast malloc like int *a=(int)malloc(size of(int)) or it is done implicitly.

    • @PortfolioCourses
      @PortfolioCourses  Рік тому

      @@yogeshchauhan9401 No, we don't need to do that in C. In C++, we do need to do that. 🙂

  • @Whoeveriam226
    @Whoeveriam226 Рік тому

    0:45 array[1] is a pointer the the FIRST ELEMENT of the array you said it was pointing to. &array[1] points to the entire array

    • @PortfolioCourses
      @PortfolioCourses  Рік тому

      This video covers this distinction for anyone that wants to learn more: ua-cam.com/video/WL1P6xiA_KY/v-deo.html. As a practical matter, for what I'm talking about here there isn't an important difference, the memory address in both cases and the related ideas will be the same.

  • @wscamel226
    @wscamel226 3 місяці тому +1

    Perfect. Exacly what I needed. Thank you so much

  • @vykuntamyogasimha
    @vykuntamyogasimha Рік тому +1

    Such a great explanation , been referencing many books but this video has made it clear ❤👌💕

    • @PortfolioCourses
      @PortfolioCourses  Рік тому

      Thanks so much Vykuntam, I’m really glad to hear the explanation helped you out! :-)

  • @nicolaikystaubayev5877
    @nicolaikystaubayev5877 Рік тому

    Thanks for the great video! Just wondering what editor you use for C in this video? It looks nice and tidy!

  • @HansBezemer
    @HansBezemer 10 місяців тому +1

    You have to throw a little code to it, but one could handle 2D arrays "the Forth way". Which means allocating just the array and let the runtime figure out the nitty gritty details. You can make as many 2D arrays you want this way - and with a bit of effort you can even resize them. The overhead is just 2 elements; the first and the second. You might be surprised at the lvalue, but it is legal. It is a dereferenced pointer expression. The *#define* is just there to remove a bit of the ugliness. Don't judge too hard on a quick hack ;-)
    #include
    #include
    #define A2D(a,b,c) *(array2d((a),(b),(c)))
    int* make2darray (int rows, int cols)
    {
    int* a = (int*) calloc (rows * cols + 2, sizeof(int));
    if (a == NULL) return (NULL);
    a [0] = rows; a [1] = cols; return (a);
    }
    int* array2d (int* a, int row, int col)
    {
    if ((row < a[0]) && (col < a[1])) return (a + 2 + col + a[1] * row);
    return (a + 2); /* just limit possible corruption, avoid segfaults */
    }
    int main (char** argv, int argc)
    {
    int* a;
    if ((a = make2darray (3,5)) == NULL) return (1);
    A2D(a, 2, 3) = 5;
    printf ("%d
    ", A2D(a, 2, 3));
    return (0);
    }

    • @tomaszstanislawski457
      @tomaszstanislawski457 16 днів тому

      Or just use a pointer to a first row of 2D array. I mean `int (*arr)[cols] = calloc(rows, sizeof *arr);`. That's all. Use `arr[y[x[` for access, remember to call `free(arr)` at the end.

  • @wc3815
    @wc3815 2 роки тому

    OMG thank you so much!! I was struggling with 2d arrays in my assignment, you got a sub!
    also are you coding in vscode? How to get plain white text background 😲

    • @PortfolioCourses
      @PortfolioCourses  2 роки тому +1

      You're welcome! :-) In this video I'm coding with Xcode on a Mac. In other videos I do code with VS Code with a white background, and I use the color theme "Light (Visual Studio)".

  • @fifaham
    @fifaham Рік тому

    Very simple and easy to understand explanation - many thanks.

    • @PortfolioCourses
      @PortfolioCourses  Рік тому +1

      You're welcome Firas, I'm glad you found it simple and easy to understand! :-)

  • @mouadflp1480
    @mouadflp1480 2 роки тому

    you are great ms portfolio , i really thank you !!!!!

  • @GodsOnlyMonster
    @GodsOnlyMonster 2 роки тому

    I was waiting for this video for so so long when I wanted to learn about dynamically allocating 2D array few days ago I was not able to find video from your channel and got sad

  • @andranikarakelov8139
    @andranikarakelov8139 2 роки тому +1

    Thanks for video,can you please make another one same concepts but with incrementation, i want build 2d array but the size dynamicly incremented by for loop,i tried with realloc but i messed up 😅

    • @PortfolioCourses
      @PortfolioCourses  2 роки тому

      Yes I think I could do a video like that sometime. Which dimension are you trying to increase in size, the rows, or the columns, or both? And why is it being increased in size in a loop? Is the thing that you’re tying to do written down anywhere as an exercise? I’m just asking these questions so I can better understand the problem you are trying to solve. :-)

    • @andranikarakelov8139
      @andranikarakelov8139 2 роки тому

      Well i want to manip file content "characters" into 2d array, but i'am using system file i/o not fopen ones. So i get each caracter one by one and yes it is like you are building 2d array and at row 0 you are incrementing col till you hit '
      ' means new line then you increment row +1 etc

    • @PortfolioCourses
      @PortfolioCourses  2 роки тому +1

      @@andranikarakelov8139 OK, hopefully I can do a video one day on this sort of realloc() of 2D arrays!

  • @MIbrahim-b3j
    @MIbrahim-b3j 10 місяців тому

    Clear explanation,😇

  • @xMo-101
    @xMo-101 5 місяців тому

    literally awesome

  • @AnalogDude_
    @AnalogDude_ 8 місяців тому

    14:31 should be "delete array; array = NULL;", otherwise you can still add new data albeit having a different address.

  • @HLubenow
    @HLubenow 11 місяців тому

    Ok, but how do you initialize? With arrays, I can do:
    int array[2][3] = {{1, 2, 3}, {4, 5, 6}};
    How would I do this with pointers and malloc()?
    Especially, if I only want to store the data in the allocated memory, that I can "free()" lateron.

    • @PortfolioCourses
      @PortfolioCourses  11 місяців тому

      You could use loops to initialize the arrays, or memset or memcpy should work as well! :-)

  • @GodsOnlyMonster
    @GodsOnlyMonster 2 роки тому

    Please make a video showing how to make 2d array Static row and dynamic column and with dynamic row and static column as well brother

  • @harveykisiangani9939
    @harveykisiangani9939 Рік тому

    Soooo, so helpful, God bless

  • @Abc-me2cx
    @Abc-me2cx Рік тому

    why aren't you puttng (int*) typecasting before malloc, please let me know

    • @PortfolioCourses
      @PortfolioCourses  Рік тому +3

      We don't need to do that in C, only in C++ do we need to do that. :-)

  • @mineshbhavsar5851
    @mineshbhavsar5851 Рік тому

    Sir I think a double pointer is created on a stack not in a Heap

    • @PortfolioCourses
      @PortfolioCourses  Рік тому

      Yes, the pointer variable itself is on the stack, but the memory it points to is generally on the heap. :-) When talking about pointers we might refer to what they're pointing to in a casual way when talking about the variable and say "X is on the heap", etc, because that's what really matters in that context.

    • @geraa641
      @geraa641 10 місяців тому

      so is the double pointer itself is on the stack and the pointer like point[0] is in the heap, then the pointer point to another address in the heap? like stack-> heap->heap?

  • @mastermax7777
    @mastermax7777 11 місяців тому

    at 9:40 , why is array[0] starting at memory location 24?

    • @schifoso
      @schifoso 8 місяців тому

      Because the alignment is 8 bytes.

  • @goktugparlak1618
    @goktugparlak1618 11 місяців тому

    Sir why array's memory adress is 12 and array[0]'s is 24 why they are not the same isn't it inside of the same memory.Also why array[0] memory adress is 24 and array[0][0] 's is 64 isn't it should be goes array[0] ==24 array[0][0]==24 then array[0][1]==28 array[0][2]==32 like this. I think the other one is inside of it

    • @schifoso
      @schifoso 8 місяців тому

      array is allocated and the memory for it starts at 12. It is an array of 3 empty pointer holders. Each holder will end up containg a pointer to row data. So these 3 empty pointer holders are part of the column. In the explanation shown, array has a value of 12 in the Address column and 24 in the Value column. 12 is the Address of array, and 24 is actually the value of the first entry in what array points to. It's the value of array[0].
      Now for each column, memory is allocated for the row data (the row data is the three integer values such as "1, 2, 3"). Each row allocation returns a pointer to where the row data for the values reside. The returned row pointer is stored in the associated column slot; there are three allocations for rows and the returned allocation values will go into the coin slots of array[0], array[1], and array[2]. In the example given, the three allocations returned pointer values 64, 80, and 96. So array[0] contains 64 as a value, which in the you can see 64 in the Value column. No when you go to 64 in the Address column, your looking at the start of the data for the first row. So this column will contain the first integer in the row, which is shown in the Value column as the number 1. The address 64, 68, and 72 contain the values of the first row of integers - 1, 2, and 3.
      Next row address is stored in array[1]. array[1] has 32 under the Address column, and 80 in the Value column. 32 is the address of array[1], and what exists at that address is the Value 80, and that 80 is the address of the next row off data. This then just repeats for the number of rows defined.
      The address values may look a bit strange...
      Notice how array[0] is 64 and array[1] is 80, which is a difference of 16 bytes. But the row pointed to by array[0] - the data for the row - only contains 3 integers. Each integer takes up 4 bytes, so the data required to hold those 3 integers is 12 bytes. So the memory location to hold those 12 bites starts at 64 and goes for 10 bytes out to memory location 75 (inclusive). That means there is nothing at memory locations 76, 77, 78, and 79 - equally a hole. This seemingly empty space could actually be use by the memory allocator to store information about allocated memory, or it could be there because memory allocations must occur on 8 byte boundaries and 76 is not on an 8 byte boundary but 80 is. Allocations on an 8 byte boundary would also explain the memory address of array as it holds an 8 byte pointer so if doesn't end (memory address 19) on an 8 byte boundary.

  • @fogter2678
    @fogter2678 11 місяців тому

    legend

  • @fusca14tube
    @fusca14tube 2 роки тому

    Hi... your videos are great! Tip... instead of using int to store rows ans cols, use #declare. ;)

    • @PortfolioCourses
      @PortfolioCourses  2 роки тому +1

      Thanks! Totally agreed #declare is great for setting cols/rows, but if we wanted to accept the values for cols/rows as user input we would need variables. 🙂

  • @Robbinsffxi
    @Robbinsffxi 8 місяців тому

    It would be easier to learn if I understood the usecase for this.

    • @PortfolioCourses
      @PortfolioCourses  8 місяців тому +1

      We use 2D arrays for things like matrices in mathematics. Dynamic allocation lets us allocate memory at runtime so the 2D arrays can vary in size when the program executes.

    • @Robbinsffxi
      @Robbinsffxi 8 місяців тому

      @@PortfolioCourses I see. Thank you.

  • @Architector120
    @Architector120 2 роки тому

    i'm just imagining how painful it would be to make a 4D array...

    • @PortfolioCourses
      @PortfolioCourses  2 роки тому +3

      I've thought of doing something like that purely for the "fun" of it. 🙂

  • @osmangokturk5154
    @osmangokturk5154 Рік тому

    instead of 3*3, 3*5 could make more sense

    • @PortfolioCourses
      @PortfolioCourses  Рік тому

      Hmm maybe, I was trying to keep the size smaller to illustrate things. :-)