Why is the value in bytes displayed as 4?

3

I'm using a 2x2 array with a simple pointer and I want to display the values of it.

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

typedef struct matriz mat;

struct matriz {

    int lin;
    int col;
    int *arr;
};

mat* cria(int lin, int col) {

    mat *m = malloc(sizeof(mat));
    m->lin = lin;
    m->col = col;
    m->arr = malloc(lin * col * sizeof(int));
    return m;
}

void exibe(mat *m) {

    for(size_t i = 0; i < sizeof(m->arr); i++) {
        printf("%3d", m->arr[i]);
    }
}
int main() {

    mat *m;
    m = cria(2, 2);
    m->arr[0] = 24;
    m->arr[1] = 16;
    m->arr[2] = 13;
    m->arr[3] = 56;

    exibe(m);

    return 0;
}

So sizeof(m->arr) displays 4. It should not display 16 bytes (4 x 4)?

    
asked by anonymous 05.04.2017 / 04:03

2 answers

3

No. What is stored in m->arr ? The return from malloc() , which is a pointer. In 32-bit architecture a pointer has 4 bytes, if you want the size of the sequence, it has to pass as argument to the function. But I have the impression that neither is the case, what you want is the amount of elements, which should also pass. Since the structure has this information, you do not even have to pass anything, you can only use lin * col .

In fact this code seems to have other problems, but I did not dig deep. And the code is not creating any matrix, just a simple sequence.

    
05.04.2017 / 04:11
1

The program you want should look like this:

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

typedef struct matriz mat;

struct matriz {
    int lin;
    int col;
    int *arr;
};

mat* cria(int lin, int col) {
    mat *m = malloc(sizeof(mat));
    m->lin = lin;
    m->col = col;
    m->arr = malloc(lin * col * sizeof(int));
    return m;
}

void destroi(mat *m) {
    if (m == NULL) return;
    free(m->arr);
    free(m);
}

int ler_elemento(mat *m, int i, int j) {
    return m[i * m->col + j];
}

int definir_elemento(mat *m, int i, int j, int valor) {
    m[i * m->col + j] = valor;
}

void exibe(mat *m) {
    for (int i = 0; i < m->lin; i++) {
        for (int j = 0; j < m->col; j++) {
            printf("%3d ", ler_elemento(m, i, j));
        }
        printf("\n");
    }
}

int main() {
    mat *m;
    m = cria(2, 2);
    definir_elemento(m, 0, 0, 24);
    definir_elemento(m, 0, 1, 16);
    definir_elemento(m, 1, 0, 13);
    definir_elemento(m, 1, 1, 56);

    exibe(m);
    destroi(m);

    return 0;
}

Note that I created the ler_elemento and definir_elemento functions to center, abstract, and encapsulate the logic of accessing the elements in the correct positions. In this way, the other parts of the code do not have to worry about the more complicated details of how to find the correct position in the matrix element array, and you will not even have to worry about knowing that the mat structure has an array there inside. So if you later want to change how the mat structure organizes your data, only the ler_elemento , definir_elemento , and cria functions will need to be changed, which avoids cascade changes, where the change of a small detail would force the need to promote major changes in the whole code.

I also added a function to deallocate mat . It is a good practice to always deallocate what you allocate, and so whenever you have a function that creates something by means of dynamic memory allocation, you should immediately have to hand the function that deallocates the same thing. >

As for sizeof(m->arr) , this will give you the size of the m->arr pointer rather than the size of the array. Note that arr is of type int * , and therefore sizeof(m->arr) is the same as sizeof(int *) . The result is 4 because a pointer to integer occupies 4 bytes on your computer, no matter where that pointer points to, or whether it points to a valid memory address or not.

The purpose of sizeof is to measure how much static memory a given structure occupies, and it is determined at compile time rather than execution time. For dynamic memory allocation, the size of the data allocated depends on information that is only available at runtime, and therefore there is no way for the compiler to know what it would be. The solution is you calculate the size yourself if you need, and in the end, you do not need that to just display the array on the screen.

    
05.04.2017 / 18:01