0

I am trying to allocate a 2D matrix in C, that's already inicialized. I need it already inicialized to form the table of contents that will be used after for the next functions.

the matrix

char matriz2D[8][24] ={{'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'},
                            {'#','\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '#'},
                            {'#','\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '#'},
                            {'#','\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '#'},
                            {'#','\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '#'},
                            {'#','\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '#'},
                            {'#','\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '#'},
                            {'#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#', '#'}};

How i could allocate it? I am trying the code

matriz2D[alocador1][alocador2] =(char**)malloc(sizeof(char));

But the compiler throws me the error:

error: assignment to 'char' from 'char **' makes integer from pointer without a cast [-Wint-conversion]

How i can proceed to allocate in memory this matrix?

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • You cannot allocate a matrix that is already initialized, except for `calloc` to initialize memory to zero. `malloc` gives you uninitialized memory. You have to put data in it in a separate step. What do you mean that “trying to allocate a 2D matrix in C, that's already inicialized”? – Eric Postpischil Jul 25 '23 at 17:27
  • It's because when i try to pass the matrix to a function, it throws me a memory out of bounds error, thus indicating that the matrix is not acessed by the matrix – gustavo moretto itikawa Jul 25 '23 at 17:51
  • 2
    @gustavomorettoitikawa "because when i try to pass the matrix to a function ..." --> Post that sample code. – chux - Reinstate Monica Jul 25 '23 at 18:05
  • The code of the functions as follows, i am trying to make a basic pathfinder function to later use, but the functions throw me a memory out of bounds when i try to use the data inside the matrix, like in the statement `if(matrix[element_positionY+1][element_position]!='\0') { printf("The cell above is clear!\n"); return VALID_MOVEMENT; }else { printf("The position above is occupied!\n"); return INVALID_MOVEMENT; }` – gustavo moretto itikawa Jul 25 '23 at 18:51
  • Read this: [**Correctly allocating multi-dimensional arrays**](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays) – Andrew Henle Jul 25 '23 at 19:10

4 Answers4

1

You can not allocate dynamically an initialized array except that the function calloc can initialize the allocated memory by zeroes.

So at first you need to allocate memory for the two-dimensional array and then set its elements as required.

To allocate the matrix dynamically as a two-dimensional array you can write for example

enum { M = 8, N = 24 };
char ( *matriz2D )[N] = calloc( 1, sizeof( char[M][N] ) );

memset( matriz2D[0], '#', sizeof( matriz2D[0] ) );
memset( matriz2D[M-1], '#', sizeof( matriz2D[M-1] ) );

for ( size_t i = 1; i < M-1; i++ )
{
    matriz2D[i][0] = '#';
    matriz2D[i][N-1] = '#';
}

Pay attentfion to that instead of the magic numbers 8 and 24 it is better to use named constants. Also bear in mind that elements of the matrix do not contain strings.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

There are many ways to write this. The way to go depends on the way you will use the area.

First question to ask is if the matrix dimensions is always the same

If char[8][23] is all you will need I will show you an example of a simpler way to write this.

Anyway you need to know that char ** is another thing and must be constructed carefully, as char ** ** is. These are very useful constructs but may be here you do not need them.

If your use case is for something more dynamic write back and I can post an alternative using char ** or something else.

output of the example

Set 1 [ a b c d e f ]
Set 2 [ g h i j k l ]

allocating new area for matrix

copy set 1 to new area
In new area: [ a b c d e f ]

copy set 2 to new area
In new area: [ g h i j k l ]

free()'ing memory

Example C code

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

typedef char(Target)[2][3];
int print_set(Target*, const char*);

int main(void)
{
    Target set_1 = {{'a', 'b', 'c'}, {'d', 'e', 'f'}};
    Target set_2 = {{'g', 'h', 'i'}, {'j', 'k', 'l'}};

    print_set(&set_1, "Set 1");
    print_set(&set_2, "Set 2");

    printf("\nallocating new area for matrix\n");
    Target* pTarget = (Target*)malloc(sizeof(Target));

    printf("\ncopy set 1 to new area\n");
    memcpy(pTarget, set_1, sizeof(Target));
    print_set(pTarget, "In new area:");

    printf("\ncopy set 2 to new area\n");
    memcpy(pTarget, set_2, sizeof(Target));

    memcpy(pTarget, set_2, sizeof(Target));
    print_set(pTarget, "In new area:");
    printf("\nfree()'ing memory\n");
    free(pTarget);
    return 0;
};

int print_set(Target* tgt, const char* title)
{
    if (tgt == NULL) return -1;
    printf("%s [ ", title);
    for (size_t a = 0; a < 2; a += 1)
    {
        for (size_t b = 0; b < 3; b += 1)
            printf("%c ", (*tgt)[a][b]);
    }
    printf("]\n");
    return 0;
}

The typedef is just for readability. print_set() is an example of how to pass the area as a whole.

arfneto
  • 1,227
  • 1
  • 6
  • 13
0

Don't make it hard. Use a struct.

struct your_matrix_s {
   char matriz2D[8][24];
};
struct your_matrix_s *matrix = malloc(sizeof(*matrix));

Do not cast result of malloc.

If you are up for a challenge, then you might want a pointer to an array:

char (*another_matrix)[24] = malloc(8 * sizeof(*another_matrix));
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
0

You already have allocated the matrix. Just not dynamically.

Given that this matrix is not prohibitive in size to have on the stack, the only reason you'd need to dynamically allocate would be if you're creating it within one function and need it to survive that function's lifetime.

Your question hints your problem lies in passing this to a function. When your matrix is passed to a function it decays to a pointer, but what kind of pointer? Well, it decays to a pointer to an array of 24 characters.

If you try to write the following, you will get warnings from your compiler and then in my testing, a segmentation fault.

void foo(char **m) {
    m[0][0] = 'A';
}
test.c:33:9: warning: incompatible pointer types passing 'char[8][24]' to parameter of type 'char **' [-Wincompatible-pointer-types]
    foo(matriz2D);
        ^~~~~~~~
test.c:3:17: note: passing argument to parameter 'm' here

But, if you write the following, then your function arguments are properly typed and it works as expected.

void foo(char (*m)[24]) {
    m[0][0] = 'A';
}

If you need to be able to pass matrices with different dimensions, we can pass a size_t argument as well.

void foo(size_t n, char (*m)[n]) {
    m[0][0] = 'A';
}

For your matrix, this would be called as:

foo(24, matriz2D);
Chris
  • 26,361
  • 5
  • 21
  • 42