Ir ao conteúdo
  • Cadastre-se

C++ Não consigo liberar espaço de memoria?


soumma

Posts recomendados

Eu to fazendo um pequeno programa em c++ usando uma estrutura e alocando dinamicamente memoria, mas eu não estou conseguindo liberar essa memoria que reservei. O estranho é que ele parece só liberar o primeiro espaço de memoria que ele entra. Eu sei que eu poderia esta trabalhando com classes mais eu quis fazer com structs. Dps de algumas modificações quando rodo e faço as chamadas das funções a IDE simplesmente trava processando a tarefa dando umas saidas estranha. Eu queria saber o que ta acontecendo com esse programa

string symbols = "2233445566778899TTJJQQKKAA";

typedef struct card {
	char symbol;
	card *next_card;
	card *back_card;
};

typedef struct {
	card *first_card;
	card *last_card;
	int num_cards;
} deck;

void init_deck(deck *deck) {
	deck->last_card = (card*) malloc(sizeof(card));
	deck->last_card->symbol = symbols[0];
	deck->last_card->back_card = NULL;
	card *p = deck->last_card;
	for (int i = 1; i < 26; i++, p = p->next_card) {
		p->next_card = (card*) malloc(sizeof(card));
		p->next_card->symbol = symbols[i];
		p->next_card->back_card = p;
		p->next_card->next_card = NULL;
	}
	deck->first_card = p;
}
      
void show_deck(deck *deck) {
	card *p = deck->last_card;
	while (p != NULL) {
		cout << p->symbol << " ";
		p = p->next_card;
	}
}
      
int main() {
	deck deck1;
	init_deck(&deck1);
	show_deck(&deck1);
	card* p = deck1.last_card;
	cout << endl << p->symbol << endl;
	free(p);
	show_deck(&deck1);
	return 0;
}

 

Link para o comentário
Compartilhar em outros sites

você tem chamar free para para cada vez que usou malloc.

No caso, tem um lação que aloca 25 variáveis na memória, além da alocação do deck.

você tem que repetir o laço, mas ao invés de alocar você teria que chamar free.

Além disso, após liberar a memória você tem que atribuir NULL ao ponteiro, free não faz isso automaticamente

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

2 horas atrás, Flávio Pedroza disse:

você tem chamar free para para cada vez que usou malloc.

No caso, tem um lação que aloca 25 variáveis na memória, além da alocação do deck.

você tem que repetir o laço, mas ao invés de alocar você teria que chamar free.

Além disso, após liberar a memória você tem que atribuir NULL ao ponteiro, free não faz isso automaticamente

Sim, eu esqueci de por o laço aqui, como  eu disse no post eu dei uma mudada no codigo, dai pra pegar a saida eu nao usei um laço pra dar free em geral mas mesmo assim só liberava um, dai começei a achar q tinha passado por valor nas funções alguma coisa desse tipo. o que eu não fiz mesmo foi dar null pra onde apontam, provavelmente foi isso mesmo XD

Link para o comentário
Compartilhar em outros sites

1 hora atrás, soumma disse:

Eu to fazendo um pequeno programa em c++ usando uma estrutura e alocando dinamicamente memoria, mas eu não estou conseguindo liberar essa memoria que reservei. O estranho é que ele parece só liberar o primeiro espaço de memoria que ele entra. Eu sei que eu poderia esta trabalhando com classes mais eu quis fazer com structs. Dps de algumas modificações quando rodo e faço as chamadas das funções a IDE simplesmente trava processando a tarefa dando umas saidas estranha. Eu queria saber o que ta acontecendo com esse programa

 

  • Poste o código completo, de modo que possa ser copiado do formulário e compilado. Se você por exemplo estiver usando um #include errado ou tiver um faltando ninguém vai poder te dizer e ajudar
  • main() deve ser a primeira função de seu programa, e se possível a única no arquivo onde está...
  • use protótipos para as funções e declare tudo no fim ou se possível em outros arquivos
  • não use variáveis globais. Não por acaso são proibidas em muitos ambientes, empresas e escolas,.e condenadas por autores e instrutores em todo o planeta. Isso só dá problema. No seu caso, symbol é parte do deck. Declare como tal.
  • struct e class são a mesma coisa nesse contexto. Apenas em struct tudo é por padrão publico.
  • Está programando em C++. Quando está programando em C++ a partir de 2011 e usa uma função init() quer dizer que tem provavelmente algo errado.
  • não retorne void. Em geral é um desperdício e muitas vezes um erro mesmo.
  • No caso de init_deck() entenda que você devia retornar o endereço do novo deck, como uma função factory. Não retornando quer dizer que tudo o que fizer lá dentro morre lá dentro. A memória que alocou some a toda chamada...
  • não use malloc() em C++. Use new ou melhor ainda use unique_ptr e não precisará se preocupar com free() ou delete porque o sistema libera sózinho a área alocada.
  • C++ tem listas disponíveis. Não precisa programar isso. Pode escrever algo como
     
        list<Card>	baralho;

Não é um bom caminho usar assim essas estruturas. Vai dar muito mais trabalho para muito menos resultado. 
 

De todo modo considere o que eu escrevi e veja essa saída
 

Deck com 26 cartas
a b c d e f g h i j k l m n o p q r s t u v x y w z
Ao final: primeira carta = a Ultima carta = z
Apagando o deck: [z w y x v u t s r q p o n m l k j i h g f e d c b a ]

 

Desse programa, que é o seu programa com umas notas
 

int main(void)
{
	Deck* deck1 = init_deck("abcdefghijklmnopqrstuvxywz");
	show_deck(deck1);
	cout << "Ao final: primeira carta = " <<
		deck1->first_card->symbol <<
		" Ultima carta = " <<
		deck1->last_card->symbol << "\n";
	deck1 = destroy_deck(deck1);
	return 0;
};	// main()

 

Veja que

  • passar os símbolos como argumento é mais produtivo: tem mais opções: pode usar o tamanho da string para controlar init_deck() e usar qualquer número de símbolos.
  • Escreva em torno dos dados e fica mais fácil de ler.
  • Retorne os endereços. Quando apaga também, assim se assegura de invalidar o ponteiro, uma causa comum de crash --- dangling pointers
  • Apagar o deck é uma operação de dois passos, como no exemplo
     
    Deck* destroy_deck(Deck* D)
    {
    	if (D == NULL) return NULL;
    	cout << "Apagando o deck: [";
    	Card* p = D->last_card;
    	while (p != NULL)
    	{
    		Card* antes = p->back_card;
    		cout << p->symbol << " ";
    		delete p;
    		p = antes;
    	};
    	delete D;
    	cout << "]\n";
    	return NULL;
    };

Eis o programa todo

#include <iostream>
#include <list>
using namespace std;


struct _card
{
	char		 symbol;
	struct _card* next_card;
	struct _card* back_card;

};
typedef struct _card Card;

struct _deck
{
	Card*		first_card;
	Card*		last_card;
	int			num_cards;
	string		symbols;

};
typedef struct _deck Deck;

Deck*		destroy_deck(Deck*);
Deck*		init_deck(string);
int 		show_deck(Deck*);


int main(void)
{
	Deck* deck1 = init_deck("abcdefghijklmnopqrstuvxywz");
	show_deck(deck1);
	cout << "Ao final: primeira carta = " <<
		deck1->first_card->symbol <<
		" Ultima carta = " <<
		deck1->last_card->symbol << "\n";
	deck1 = destroy_deck(deck1);
	return 0;
};	// main()


Deck* destroy_deck(Deck* D)
{
	if (D == NULL) return NULL;
	cout << "Apagando o deck: [";
	Card* p = D->last_card;
	while (p != NULL)
	{
		Card* antes = p->back_card;
		cout << p->symbol << " ";
		delete p;
		p = antes;
	};
	delete D;
	cout << "]\n";
	return NULL;
};


Deck*		init_deck(string symbol)
{
	Deck* deck = (Deck*) new Deck;
	deck->last_card = NULL;
	deck->num_cards = 0;
	deck->symbols = symbol;

	deck->first_card = (Card*) new Card;
	deck->first_card->back_card = NULL;
	deck->first_card->next_card = NULL;
	deck->first_card->symbol = symbol[0];

	Card* p = deck->first_card;
	int n = symbol.length();
	for (int i = 1; i < n; i += 1)
	{
		Card* nova = (Card*) new Card;
		nova->back_card = p;
		p->next_card = nova;
		nova->next_card = NULL;
		nova->symbol = symbol[i];

		p = nova; // avanca
	};

	deck->last_card = p; // era a ultima afinal
	deck->num_cards = n; // corrige
	deck->symbols = symbol; // salva
	return deck;
};


int			show_deck(Deck* deck)
{
	if (deck == NULL) return -1;
	cout << "Deck com " << deck->num_cards << " cartas\n";
	Card* p = deck->first_card;
	int count = 0;
	while (p != NULL)
	{
		cout << p->symbol << " ";
		p = p->next_card; count += 1;
	}
	cout << "\n";
	return count; // para conferir
}


Repito: não vale a pena escrever assim. 

 

Resumo curtinho
 

O maior problema do seu código é não retornar o endereço do deck. 
 

 

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!