Jump to content
Saddler

Alocação dinâmica e boas práticas de programação em C

Recommended Posts

Saddler

É verdade que é considerado uma má prática de programação C alocar memória em uma função e desalocar em outra função?

Tenho essa dúvida porque recentemente tive que fazer o uso deste recurso em um projeto que estou desenvolvendo sozinho e eu sinceramente não sei se foi uma boa abordagem ...

Segue os códigos abaixo para uma análise:

//trecho de código

struct art_properties{

    int art;
    int quote;
    int art_color;
};
//trecho de código

static void handler(int num){

    clear();
    endwin();
    init_scr();
}

int resize(int key){

    struct sigaction new_action;
    struct sigaction old_action;

    new_action.sa_flags=0;
    new_action.sa_handler=handler;

    sigemptyset(&new_action.sa_mask);
    sigaction(SIGWINCH, &new_action, &old_action);

    return getmaxy(stdscr);
}

static size_t count_rows(const char *file_path){

    size_t rows=0;
    FILE *file=fopen(file_path, "r");

    if(file!=NULL){

        while(!feof(file)){

            if(fgetc(file)=='\n'){

                rows++;
            }
        }

        fclose(file);
    }

    return rows;
}

struct art_properties *print_art(int y, struct art_properties *properties){

    struct art_properties aux;
    FILE *art_file=NULL, *quote_file=NULL;

    size_t i=0;
    char row_content[1025], str_quote[1025];

    const char *arts[]={"obj/arts/art_001.txt", "obj/arts/art_002.txt",
                        "obj/arts/art_003.txt", "obj/arts/art_004.txt",
                        "obj/arts/art_005.txt", "obj/arts/art_006.txt",
                        "obj/arts/art_007.txt", "obj/arts/art_008.txt",
                        "obj/arts/art_009.txt", "obj/arts/art_010.txt"};

    if(properties==NULL){

        srand(time(NULL));

        aux.art=rand()%9;
        aux.art_color=rand()%7;
        aux.quote=1+(rand()%count_rows("obj/quotes.txt"));

        properties=malloc(sizeof(struct art_properties));

        memcpy(properties, &aux, sizeof(struct art_properties));

    }else{

        memcpy(&aux, properties, sizeof(struct art_properties));
    }

    attron(COLOR_PAIR(aux.art_color) | A_BOLD);

    art_file=fopen(arts[aux.art], "r");

    if(art_file!=NULL){

        for(i=0; i<count_rows(arts[aux.art]); i++){

            fgets(row_content, 1025, art_file);

            mvprintw(y+i, 1, "%s", row_content);
        }

        fclose(art_file);
    }

    quote_file=fopen("obj/quotes.txt", "r");

    if(quote_file!=NULL){

        if(aux.quote!=1){

            for(int i=0; i!=aux.quote; i++){

                fgets(str_quote, 1025, quote_file);
            }

            mvprintw(y+2+i, 1, "[GANADO QUOTE] - %s", str_quote);
        }

        fclose(quote_file);
    }

    attroff(COLOR_PAIR(aux.art_color) | A_BOLD);

    return properties;
}

struct art_properties *free_art(struct art_properties *ptr){

    free(ptr);

    return NULL;
}
//trecho de código

case '0':

    noecho();

    do{

        properties=print_art(1, properties);

    	attron(COLOR_PAIR(YELLOW) | A_BOLD);
    	mvprintw(y-1, 1, "[?] - Are you sure you want to quit Saddler [Y/n]?");
    	attroff(COLOR_PAIR(YELLOW) | A_BOLD);

    	key=getch();
    	y=resize(key);

    	clear();

    	switch(key){

    	    case 'y':
    	    case 'Y':

    		key='Y';

    		break;

    	    case 'n':
    	    case 'N':

    		key='N';

    		break;

    	    default:

    		break;
    	}

    }while(key!='Y' && key!='N');

    properties=free_art(properties);

    echo();

    break;

 

-> "funcionando" -> https://imgur.com/a/n3C8n5F
________________________________________________________________________________________________________________________________________

Dúvida: Se acima eu fiz mau uso da alocação dinâmica, qual seria uma abordagem alternativa para os códigos acima? Uma solução que não afete o objetivo secundário da função print_art()?

* Objetivo secundário da função print_art() -> Mater as propriedades da arte impressa no terminal mesmo que a janela seja redimensionada.
________________________________________________________________________________________________________________________________________

Peço desculpas a todos os membros desta comunidade por não postar todo o projeto, mas é que ele ainda não está 100% finalizado e eu também não quero ser zuado por outros programadores mais experiêntes por postar "gambiarra" de 3000 linhas cheia de bugs.

Edited by Saddler
Alterações estéticas do texto

Share this post


Link to post
Share on other sites
HappyHippyHippo

respondendo sucintamente à questão essencial do tópico : não

o meu problema é com o uso do termo "objectivo secundário" ... secundário ? uma função que tem mais do que um objectivo ?


IRC : sim, é algo que ainda existe >> #p@p

Share this post


Link to post
Share on other sites
Saddler
On 7/12/2019 at 5:07 PM, HappyHippyHippo said:

respondendo sucintamente à questão essencial do tópico : não

o meu problema é com o uso do termo "objectivo secundário" ... secundário ? uma função que tem mais do que um objectivo ?

Ehhh ... Sorry. Não deixei isso muito claro. Aqui vai um código completo para melhor entendimento:

 

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <ncurses.h>

struct art_properties{

    int art;
    int quote;
    int art_color;
};

static void init_scr(void){

    if(initscr()==NULL){

        fprintf(stderr, "[X] - initscr() == NULL!\n");

        exit(EXIT_FAILURE);
    }

    if(has_colors()!=TRUE){

        endwin();

        fprintf(stderr, "[X] - Your terminal does not suport colors!\n");

        exit(EXIT_FAILURE);

    }else{

        int bkg_color;

        signal(SIGINT, SIG_IGN);
        signal(SIGTSTP, SIG_IGN);

        cbreak();
        noecho();
        keypad(stdscr, TRUE);

        start_color();

        if(use_default_colors()==OK){

            bkg_color=-1;

        }else{

            bkg_color=COLOR_BLACK;
        }

        init_pair(RED, COLOR_RED, bkg_color);
        init_pair(BLUE, COLOR_BLUE, bkg_color);
        init_pair(CYAN, COLOR_CYAN, bkg_color);
        init_pair(GREEN, COLOR_GREEN, bkg_color);
        init_pair(WHITE, COLOR_WHITE, bkg_color);
        init_pair(YELLOW, COLOR_YELLOW, bkg_color);
        init_pair(MAGENTA, COLOR_MAGENTA, bkg_color);

        refresh();
    }
}

static void handler(int num){

    clear();
    endwin();
    init_scr();
}

static int resize(void){

    struct sigaction new_action;
    struct sigaction old_action;

    new_action.sa_flags=0;
    new_action.sa_handler=handler;

    sigemptyset(&new_action.sa_mask);
    sigaction(SIGWINCH, &new_action, &old_action);

    return getmaxy(stdscr);
}

static size_t count_rows(const char *file_path){

    ssize_t rows=0;
    FILE *file=fopen(file_path, "r");

    if(file!=NULL){

        while(!feof(file)){

            if(fgetc(file)=='\n'){

                rows++;
            }
        }

        fclose(file);

    }else{

        rows=1;
    }

    return rows;
}

static struct art_properties *print_art(int y, struct art_properties *properties){

    struct art_properties aux;
    FILE *art_file=NULL, *quote_file=NULL;

    size_t i=0;
    char row_content[1025], str_quote[1025];

    const char *arts[]={"arts/art_001.txt", "arts/art_002.txt",
                        "arts/art_003.txt", "arts/art_004.txt",
                        "arts/art_005.txt", "arts/art_006.txt",
                        "arts/art_007.txt", "arts/art_008.txt",
                        "arts/art_009.txt", "arts/art_010.txt"};

    if(properties==NULL){

        srand(time(NULL));

        aux.art=rand()%9;
        aux.art_color=1+(rand()%7);
        aux.quote=1+(rand()%count_rows("quotes.txt"));

        properties=malloc(sizeof(struct art_properties));

        memcpy(properties, &aux, sizeof(struct art_properties));

    }else{

        memcpy(&aux, properties, sizeof(struct art_properties));
    }

    attron(COLOR_PAIR(aux.art_color) | A_BOLD);

    art_file=fopen(arts[aux.art], "r");

    if(art_file!=NULL){

        for(i=0; i<count_rows(arts[aux.art]); i++){

            fgets(row_content, 1025, art_file);

            mvprintw(y+i, 1, "%s", row_content);
        }

        fclose(art_file);
    }

    quote_file=fopen("quotes.txt", "r");

    if(quote_file!=NULL){

        for(int i=0; i!=aux.quote; i++){

            fgets(str_quote, 1025, quote_file);
        }

        mvprintw(y+2+i, 1, "[GANADO QUOTE] - %s", str_quote);

        fclose(quote_file);
    
    }else{

        mvprintw(y+2+i, 1, "[GANADO QUOTE] - \"Te voy a matar!\"");
    }

    attroff(COLOR_PAIR(aux.art_color) | A_BOLD);

    return properties;
}

static void free_art(struct art_properties **ptr){

    free(*ptr);
    *ptr=NULL;
}

int main(void){

    int key, y;
    struct art_properties *properties=NULL;

    init_scr();

    y=getmaxy(stdscr);

    do{

        properties=print_art(1, properties);

        attron(COLOR_PAIR(YELLOW) | A_BOLD);
        mvprintw(y-1, 1, "[i] - Press Enter key to quit");
        attroff(COLOR_PAIR(YELLOW) | A_BOLD);

        key=getch();
        y=resize();

    }while(key!=10);

    free_art(&properties);

    endwin();

    return EXIT_SUCCESS;
}

 

Na real ela não tem extamente um objetivo "segundário" e sim um único propósito, que é imprimir uma arte no terminal e manter as suas propriedades (cor, quote, arte) mesmo quando a janela for redimensionada.

Edited by Saddler

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.