Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Tentando entender malloc()

Olá pessoal! Eu gostaria de tirar uma dúvida sobre alocação de memória com matrizes. Para testar e fixar os conceitos vistos até agora no curso, eu escrevi um código parecido com o do instrutor. Segue o código:

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

int main(){
    setlocale(LC_ALL, "");

    char **str;
    int line, col, length;

    FILE *reader;

    if((reader = fopen("teste_texto.txt", "r")) == NULL){
        printf("Arquivo não encontrado.");
    }

    fscanf(reader, "%d %d", &line, &col);

    str= malloc(sizeof(char*) * line);

    for(int i = 0; i < line; i++){
        str[i] = malloc(sizeof(char) * (col + 1));
        length = sizeof(str[i]);
        printf("%d" coluna: %d\n", i,length);
    }

    for(int i = 0; i < line; i++){
        fgets(str[i], length, reader);
        printf("%s", str[i]);
    }

    fclose(reader);

    for(int i = 0; i < line; i++){
        free(str[i]);
    }
    free(str);

}

O objetivo é pegar strings do arquivo teste em questão e colocá-lo em uma matriz para que possa manipulá-lo. Eu não tive lá grande sucesso e ao colocar um 'printf' no laço, percebi que ele tem invertido o número de linhas pelo de colunas, alocando mais espaço para as colunas. Por favor me digam o que estou fazendo de errado.

2 respostas
solução!

Olá Ezequiel

Na instrução para alocar o comprimento da linha usando como referência o número de colunas, o parâmetro da função malloc já especifica o comprimento em byte para ser alocada na heap:

str[i] = malloc(sizeof(char) * (col + 1));

// Alternativa
length = sizeof(char) * (col + 1); // Seria até melhor deixar essa linha fora do loop (for)
str[i] = malloc(length);

Quando você usou o sizeof para saber o comprimento da linha, você está na verdade obtendo o comprimento de um endereço (sempre será 8 bytes 0x1122334455667788, CPU 64 - bits).

length = sizeof(str[i]);

O printf da coluna está com uma aspas (") no meio da string literal.

printf("%d" coluna: %d\n", i,length);

Mudar para:

printf("%d coluna: %d\n", i,length);

A função fget ler os dados até o limite (size | length) ou a quebra de linha (\n), caso seja o limite e não o fim da linha, a proxima iteração irá continuar na mesma linha, então neste programa você NÃO cria um limite de caractere para ler por linha no arquivo. Ex: Duas linhas de sua matriz pode ter dados de uma linha do arquivo, uma complementando a outra.


alura.c (codigo original com alterações citadas)

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

void displayMatrix(char **matrix, int line, int coluna);

int main(){
    setlocale(LC_ALL, "");

    char **str;
    int line, col, length;

    FILE *reader;

    if((reader = fopen("teste_texto.txt", "r")) == NULL){
        printf("Arquivo não encontrado.");
    }

    fscanf(reader, "%d %d", &line, &col);

    str= malloc(sizeof(char*) * line);
    length = sizeof(char) * (col + 1);
    for(int i = 0; i < line; i++){
        str[i] = malloc(length);
        printf("%d coluna: %d\n", i,length);
    }

    for(int i = 0; i < line; i++){
        fgets(str[i], length, reader);
        printf("%s", str[i]);
    }

    fclose(reader);

    displayMatrix(str, line, col);

    for(int i = 0; i < line; i++){
        free(str[i]);
    }
    free(str);

}

void displayMatrix(char **matrix, int line, int coluna) {
    printf("\n");
    for (int i = 0; i < line; i++)
    {
        printf("|");
        for (int j = 0; j < coluna; j++)
        {
            char element = ' ';
            if (matrix[i][j] != '\n' && matrix[i][j] != '\0') {
                element = matrix[i][j];
            } 
            printf(" %c ", element);
            if (j != coluna - 1) printf(",");
        }
        printf("|\n");
    }
    printf("\n");
}

teste_texto.txt

10 20
David Gaspar
Elon Musk
Mark Zuckerberg
John von Neumann
Elizabete Valda Gaspar

Saída:Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Obrigado pela ajuda e explicação.