alocaçao dinamica com matriz[ajuda~]

1. alocaçao dinamica com matriz[ajuda~]

lukas
pqplukas

(usa KUbuntu)

Enviado em 16/09/2017 - 19:01h

[ajuda] e ai glr , to aprendendo agr sobre alocaçao dinamica, e me surgiu uma duvida no exercicio:
"3) Construa um programa (main) que aloque em tempo de execução (dinamicamente)
uma matriz de ordem m x n (linha por coluna), usando 1+m chamadas a função
malloc. Agora, aproveite este programa para construir uma função que recebendo os
parametros m e n aloque uma matriz de ordem m x n e retorne um ponteiro para esta
matriz alocada. Crie ainda uma função para liberar a área de memória alocada pela
matriz. Finalmente, crie um novo programa (main) que teste/use as duas funções
criadas acima.
4) Construa um programa (main) que aloque em tempo de execução (dinamicamente)
uma matriz de ordem m x n (linha por coluna), usando 2 chamadas a função malloc.
Agora, aproveite este programa para construir uma função que recebendo os
parametros m e n aloque uma matriz de ordem m x n e retorne um ponteiro para esta
matriz alocada. Crie ainda uma função para liberar a área de memória alocada pela
matriz. Finalmente, crie um novo programa (main) que teste/use as duas funções
criadas acima."
nao entendi mt bem oq e pra fazer a respeito dessa alocaçao, tanto 1+m qt 2 chamadas.
segue meu code :
#include <stdio.h>
#include <stdlib.h>
float **Alocar_matriz_real (int m, int n) {
float **v;
int i;
if (m < 1 || n < 1) {
printf ("** Erro: Parametro invalido **\n");
return (NULL);
}
v = (float *)calloc (m, sizeof(float *));
if (v == NULL) {
printf ("** Erro: Memoria Insuficiente **");
return (NULL);
}
for ( i = 0; i < m; i++ ) {
v[i] = (float *)calloc (n, sizeof(float));
if (v[i] == NULL) {
printf ("** Erro: Memoria Insuficiente **");
return (NULL);
}
}
return (v);
}
float **Liberar_matriz_real (int m, int n, float **v) {
int i;
if (v == NULL)
return (NULL);
if (m < 1 || n < 1) {
printf ("** Erro: Parametro invalido **\n"); \
return (v);
}
for (i=0; i<m; i++){
free (v[i]);
}
free (v);
return (NULL);
}
int main (void) {
float **mat;
int l, c;
int i, j;
printf("digite o valor de m: ");
scanf("%d",&l);
printf("\ndigite o valor de n: ");
scanf("%d",&c);
mat = Alocar_matriz_real (l, c);
for (i = 0; i < l; i++){
for ( j = 0; j < c; j++){
if(i==j) mat[i][j] = 1;
}
}
mat = Liberar_matriz_real (l, c, mat);
return(0);
}



  


2. Re: alocaçao dinamica com matriz[ajuda~]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 19/09/2017 - 09:21h

Você parece ter entendido certo o caso de fazer com com 1+m alocações/desalocações, pois suas funções funcionam. Apesar disso, é possível fazer algumas melhorias:

  — O comando return não exige uso de parênteses. Você pode dizer apenas “return NULL;” ou “return v;”.

  — Não é usual imprimir mensagens de diagnóstico dentro de uma função de alocação de recursos (ou outra função qualquer numa biblioteca de funções utilitárias). Em vez disso, o normal é sinalizar o erro (o que você já está fazendo, ao retornar NULL na alocação ou não-NULL na desalocação), e deixar que quem chama a função decida como tratar a condição sinalizada. Se for necessário passar mais detalhes, você pode recorrer à variável global errno ou a outra variável global ou estática com sentido semelhante, que você mesmo pode criar.

  — Em C não é necessário nem desejável ter a conversão de tipos explícita entre o valor retornado por malloc()/calloc()/realloc(), que é do tipo void *, para outro tipo de ponteiro, pois a linguagem realiza essa conversão implicitamente. Somente seria necessário ter a conversão explícita se você estivesse usando C++. Contudo, se você estivesse usando C++, provavelmente não deveria usar as funções de alocação herdadas do C, mas sim um dos operadores de alocação nativos do C++ ou uma das classes de containers da STL (ou de outro framework, como Boost ou Qt).

  — Se acontecer uma falha após a primeira alocação, você está retornando um ponteiro nulo, mas não está limpando as áreas que já haviam sido parcialmente alocadas. Desse modo, seu código tem um bug latente de memory leak. O certo seria você liberasse as alocações anteriores caso ocorra alguma falha após a primeira alocação.

  — Ao liberar memória, geralmente não se usa a forma “ponteiro_a_ser_liberado=funcao_de_liberacao(ponteiro_a_ser_liberado ...)”, mas sim algo como “funcao_de_liberacao(ponteiro_a_ser_liberado...)” ou “funcao_de_liberacao(&ponteiro_a_ser_liberado...)”.

  — O parâmetro n não é efetivamente usado pela função de liberação. Desse modo, ele poderia ser suprimido.

No código acima, fica muito evidente o fraco acoplamento entre a matriz (que é um um vetor de vetores dinamicamente alocados) e suas dimensões, principalmente na desalocação. É necessário manter informações sobre a dimensão numa variável externa separada desde a alocação até a desalocação. Num programa longo, seria fácil cometer um erro de edição ou de digitação, e acabar informando uma dimensão errada.

O uso de apenas duas alocações ajuda a contornar essa dificuldade. Ela se baseia no fato de que cada elemento v[i] (com i entre 0 e m-1) contém um endereço (ponteiro) de um array de n valores. No caso anterior, cada um desses endereços era gerado a partir de uma alocação explícita de espaço para n elementos, mas nada obriga que assim seja. Você poderia fazer uma alocação de um blocão grande o suficiente para todos os elementos da matriz, e alimentar o vetor de vetores com endereços de posições intermediárias dentro desse blocão.

Esse arranjo tem duas vantagens: desperdiça menos memória com overhead de alocação (tipicamente cada alocação requer um número de bytes a mais, além daqueles que foram solicitados explicitamente, para que as funções free() e realloc() saibam tratar aquele ponteiro nos casos de liberação e realocação, respectivamente) e libera o usuário de ter de carregar a informação de dimensões até a desalocação.

Existem desvantagens também. A principal, entre as de que consigo pensar agora, é que eventuais mudanças de dimensão da matriz podem ser mais trabalhosas, requerendo mais código explícito, do que com um ponteiro separadamente alocado para cada linha.


ATENÇÃO: Quando você implementar o exercício 4, lembre-se de que ponteiros alocados de um jeito não podem ser passados à função de desalocação do outro jeito. À alocação feita em 1+m passos tem de corresponder a desalocação em 1+m passos, que vai receber como parâmetros a matriz e o valor de m, e à alocação feita em 2 passos deve corresponder a desalocação em dois passos, que recebe apenas a matriz como parâmetro.


3. Re: alocaçao dinamica com matriz[ajuda~]

Laís Sousa Cavalcante
laislais

(usa Outra)

Enviado em 02/12/2017 - 21:47h

Lukas, tudo bem? Tu conseguisse dar continuidade ao código? Também estou com problemas com esse mesmo exercício.






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts