Executando verificação de segurança...
1

Porque redirecionar a entrada de um executável faz com que a quantidade de memória alocada aumente?

Boa noite!

Recentemente me vi brincando com a linguagem C novamente e percebi que ao redirecionar a entrada padrão do código com um arquivo de entradas pré-configuradas, a memória alocada aumentou em quase 3 mil bytes (checado com valgrind), sendo que a input string era exatamente a mesma.

Gostaria de saber o porque de isso acontecer, alguém tem uma pista?

Carregando publicação patrocinada...
2

Nao sou o mais profissional no assunto mas posso dar uns pitacos.

primeiro que alocação de memória pode ser afetada pelo redirecionamento de entrada padrao em C devido a forma como a entrada é processada pelo programa ai eh quando a entrada é lida do console, o programa aloca espaço suficiente na memória para armazenar os dados de entrada conforme eles são lido. isso e pq o programa pode usar o mínimo possível de memória para armazenar os dados de entrada, já que ele só precisa alocar memória conforme necessário.

Ai vem o porem nesse role que é quando a entrada é redirecionada de um arquivo, o programa não tem como saber a quantidade de dados que serão lidos de antemão, pois claro que ele precisa alocar uma quantidade de memória suficiente para armazenar toda a entrada de uma só vez. Isso pode resultar em uma alocação de memória maior do que a necessária, já que o programa precisa reservar espaço para o pior caso.

e pode ser tbm que o próprio redirecionamento de entrada pode exigir mais recursos de memória do sistema operacional para manipular a entrada de arquivo. Isso pode fazer com que o programa utilize mais memória para gerenciar a entrada.

Resumindo essa bagaca toda ai deixando claro que a diferença na alocação de memória pode variar dependendo da implementação do programa e do sistema operacional. É possível que outros fatores estejam contribuindo para o aumento na alocação de memória que você observou.

1
1

Cara, mostra a parte do seu código responsável pela leitura da entrada padrão. Dependendo de como você está lendo, pode ser que essa alocação de memória esteja sendo superdimensionada por vários motivos.

1

Opa, Andre (ou André, não sei)!

Segue abaixo a função:

char * read_line(FILE * stream) {
    char * buffer = (char *) malloc(sizeof(char) * MAX_BUFFER_SIZE);
    
    int read = strlen(fgets(buffer, MAX_BUFFER_SIZE, stream));

    if(read < MAX_BUFFER_SIZE && buffer[read - 1] == '\n') {
        buffer[--read] = '\0';
    }

    printf("characters read: %d\n", read);

    return buffer;
}
1
1

Se der ruim no codigo voce nao tem como saber, fica top se implementar algo para verificar erros, Cuidado com esses MAX_BUFFER_SIZE, deixa ele definido no comeco do codigo e bem visivel e colocando uma cerejinha no topo desse bolo, usa typedef

algo assim oh (nao ta dos melhores codigos) testa e faca suas melhorias:

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

#define MAX_BUFFER_SIZE 1024

typedef char* LinePtr;
typedef FILE* FilePtr;

LinePtr read_line(FilePtr stream) {
    if (!stream) {
        perror("Error: Stream pointer is NULL.");
        return NULL;
    }

    LinePtr buffer = (LinePtr) malloc(sizeof(char) * MAX_BUFFER_SIZE);

    if (!buffer) {
        perror("Error: Memory allocation failed.");
        return NULL;
    }

    LinePtr line = fgets(buffer, MAX_BUFFER_SIZE, stream);
    if (!line) {
        free(buffer);
        return NULL;
    }

    int read = strlen(line);
    if (read > 0 && line[read - 1] == '\n') {
        line[--read] = '\0';
    }

    printf("Characters read: %d\n", read);

    return line;
}
1
1

Absolutamente correto, eu meio que copie o codigo dele e fiz umas alteracoes.

Casteando malloc voce assume que LinePtr seja definido como um ponteiro para uma estrutura que contém uma matriz char e que o tamanho da estrutura seja igual a sizeof(char) * MAX_BUFFER_SIZE. Se o tamanho da estrutura não for igual a sizeof(char) * MAX_BUFFER_SIZE, isso pode resultar em erros de alocação de memória ou comportamento indefinido.

O que o @kht propoz simplesmente aloca um bloco de memória de tamanho MAX_BUFFER_SIZE e retorna um ponteiro para o início do bloco.

muito mais simples.

Nao esquece que não é necessário converter o valor de retorno de malloc em C, pois o ponteiro void retornado por malloc pode ser convertido implicitamente em qualquer outro tipo de ponteiro.