0

Hey guys i tried to build array2d dynamically but it doesnt work and said no have place its my code

int i = ZERO;
int j = ZERO;
int lenRow = ZERO;
int rows = ZERO;

printf("Enter number of rows: ");
scanf("%d", &rows);

int** arr = malloc(rows * sizeof(int*));
if (NULL == arr)
{
    printf("Unseccess");
    return 1;
}
for (i = ZERO; i < rows; i++)
{
    printf("Enter array length for row %d: ", i);
    scanf("%d", &lenRow);

    arr[i] = malloc(lenRow * sizeof(int));

    for (j = ONE; j <= lenRow; j++)
    {
        printf("Enter value for array: ");
        scanf("%d", &arr[j]);
        if (NULL == arr[j])
        {
            printf("Unseccess");
            return 1;
        }
    }
}
free(arr);

So the question its how i print this in this format

3 1 5 2 3 1 8

Aviel Ovadiya
  • 69
  • 1
  • 2
  • 10
  • 2
    pointer of pointer is not a 2D array. It is a way to fragment your memory.... – LPs Apr 28 '17 at 11:41
  • 2
    moreover you should add `for (i = 0; i < rows; i++) free(arr[i]);` to free all the rows before to `free(arr);` – LPs Apr 28 '17 at 11:45
  • `for (j = 1; j <= lenRow; j++)` ---- must be ---> `for (j = 0; j < lenRow; j++)` – LPs Apr 28 '17 at 11:46
  • `scanf("%d", &arr[j]);` -> `scanf("%d", &arr[i][j]);` – Lundin Apr 28 '17 at 11:53
  • 1
    [Correctly allocating multi-dimensional arrays](http://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays). – Lundin Apr 28 '17 at 11:53
  • 1
    You may be better off doing a single allocation of `rows * lenRow * sizeof (int)` and calculate the offset to access specific elements. – pmg Apr 28 '17 at 11:54
  • @pmg Yes, however what you propose is the C90 way of doing things. See the bottom of the link I posted for the way to do this in modern C. – Lundin Apr 28 '17 at 11:55
  • @Lundin: I'm so happy C11 made VLA optional :-) – pmg Apr 28 '17 at 11:58
  • @pmg That's naive. VLA:s filled a hole in the C type system, because they allow you to have a _pointer_ to an array of certain sizes, even when the array dimensions weren't known at compile-time. This makes code more readable and type safe. Actual VLA arrays, I don't use much. Pointers to VLA:s, I use all the time. For this reason, no C11 compiler would be dysfunctional enough not to support VLA:s. That VLA:s turned optional is likely just a result about Microsoft lobbying, because they are still whining about having to update their compiler to the year 1999 version of the standard. – Lundin Apr 28 '17 at 12:02
  • I agree with you @Lundin. Just thought I'd be the devil's advocate for a bit. And if you're stuck with a compiler without VLA support, it's good to know how to do multi-dimension "arrays" the old way. – pmg Apr 28 '17 at 12:08

1 Answers1

1

Your code should look like

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int i = 0;
    int j = 0;
    int lenRow = 0;
    int rows = 0;

    printf("Enter number of rows: ");
    scanf("%d", &rows);

    int** arr = malloc(rows * sizeof(int*));

    if (NULL == arr)
    {
        printf("Unseccess\n");
        return 1;
    }

    for (i = 0; i < rows; i++)
    {
        printf("Enter array length for row %d: ", i);
        scanf("%d", &lenRow);

        arr[i] = malloc(lenRow * sizeof(int));

        if (arr[i] != NULL)
        {
            for (j = 0; j < lenRow; j++)
            {
                printf("Enter value for array: ");
                scanf("%d", &arr[i][j]);
            }
        }
        else
        {
            printf("Unseccess\n");
            return 1;
        }

    }
    for (i = 0; i < rows; i++)
        free(arr[i]);

    free(arr);
}

Many things:

  1. You are not allocating a 2D array: you are allocating a matrix where rows can have different length
  2. indices of matrix, using start form 0 up to len-1, so for (j = 1; j <= lenRow; j++) ---- must be ---> for (j = 0; j < lenRow; j++)
  3. Freeing a pointer to pointer dynamically allocated you must de-allocate all rows first. 4.Each element of a row is "pointed" using 2 coordinates [row][col] so scanf("%d", &arr[j]); must be scanf("%d", &arr[i][j]);
  4. Lastly you must always check the malloc return value before tio use it

EDIT

To print inserted data you must trace all width of each row, like:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    int i = 0;
    int j = 0;
    int lenRow = 0;
    int rows = 0;

    printf("Enter number of rows: ");
    scanf("%d", &rows);

    int** arr = malloc(rows * sizeof(int*));
    int *widths = malloc(rows * sizeof(int));

    if ((NULL == arr) || (widths == NULL))
    {
        printf("Unseccess\n");
        return 1;
    }

    for (i = 0; i < rows; i++)
    {
        printf("Enter array length for row %d: ", i);
        scanf("%d", &lenRow);

        widths[i] = lenRow;

        arr[i] = malloc(lenRow * sizeof(int));

        if (arr[i] != NULL)
        {
            for (j = 0; j < lenRow; j++)
            {
                printf("Enter value for array: ");
                scanf("%d", &arr[i][j]);
            }
        }
        else
        {
            printf("Unseccess\n");
            return 1;
        }

    }

    for (i=0; i<rows; i++)
    {
        for(j=0; j<widths[i]; j++)
        {
            printf("Matrix[%d][%d] = %d\n", i, j, arr[i][j]);
        }
    }

    for (i = 0; i < rows; i++)
        free(arr[i]);

    free(arr);
    free(widths);
}
LPs
  • 16,045
  • 8
  • 30
  • 61