Alocação Dinâmica de matriz [RESOLVIDO]

1. Alocação Dinâmica de matriz [RESOLVIDO]

Moises Viana Felipe
viana3

(usa openSUSE)

Enviado em 09/11/2013 - 13:42h

Pessoal estou tentando fazer um programa que leia 20 nomes de times de futebol e seus 11 jogadores, para isso estou tentando usar uma alocação dinâmica de vetores(uma matriz), mas está dando erro de compilação, alguém poderia ajudar-me? Segue o código abaixo:


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

struct jogador {
char nome[40];
};

int main(){
int i,j;
struct jogador *Treze[22][22];
Treze = (struct jogador*) malloc(22*sizeof(struct jogador));

for (i=0;i<11;i++){
for(j=0;j<11;j++){
printf("Digite o nome do time %d e dos jogadores %d: \n", i+1,j+1);
scanf("%s",Treze[i][j].nome);}

}
printf("Time do Treze: \n");
for(i=0;i<11;i++){
for(j=0;j<11;j++){
printf("%s \n", Treze[i][j].nome);

}
}



return 0;
}




  


2. MELHOR RESPOSTA

Paulo
paulo1205

(usa Ubuntu)

Enviado em 09/11/2013 - 17:09h

No seu programa, o símbolo Treze (que, aliás, é um nome bem estranho para um objeto que não é um inteiro constante com o valor 13) é um array com 22 elementos, e o tipo de cada um desses elementos é um array com 22 elementos, e o tipo desses elementos é ponteiro para char.

Um array não pode aparecer no lado esquerdo de uma expressão de atribuição, pois um array, em C, não é uma variável, mas sim uma referência imutável (i.e. invariável) a um bloco específico de memória. Apenas os elementos de um array podem ser considerados variáveis, desde que eles mesmos não sejam arrays. Veja:

char *array_de_array_de_pont_para_char[10][20];
/*
Isso lê:
"array_de_array_de_pont_para_char" é um array com dez elementos que são
(individualmente) arrays com vinte elementos que são
(individualmente) ponteiros para caracteres.
*/

array_de_array_de_pont_para_char=NULL; /* Inválido: array como destino de atrubuição. */
array_de_array_de_pont_para_char[1]=NULL; /* Inválido: o segundo elemento do array mais
externo é também um array, e não pode ser
destino de atrubuição. */
array_de_rray_de_pont_para_char[9][19]=NULL; /* OK: o último elemento da matriz, tomado
individualmente, é uma variável. */


Quando você declarou Treze como uma matriz (array de arrays ou vetor de vetores), você já tirou espaço para a alocação dinâmica. Seguindo por essa linha, a forma mais simples de consertar seu programa seria remover o ponteiro da declaração e suprimir a chamada a malloc(). Só fazendo isso, o resto do programa deve funcionar sem qualquer outra intervenção.

No entanto, pelo que você disse, seu objetivo inicial era justamente treinar alocação dinâmica. Nesse caso, a forma de consertar o programa seria remover da declaração as dimensões fixas do array, e colocar um nível de ponteiro para cada dimensão fixa removida.

No seu caso, como você quer vinte times, cada um deles com onze jogadores, você poderia fazer usar uma das seguintes abordagens.

/* --- EXEMPLO COM ALOCAÇÃO FIXA --- */

struct jogador Conjunto_Times[20][11]; /* conjunto de 20 times, cada um com 11 jogadores. */

/*
Aqui você coloca código que usa ``Conjunto_Times´´, lembrando que toda manipulação que você fizer
só poderá ser no nível de jogador (i.e., você não poderá fazer ``Conjunto_Time=...´´ nem
``Conjunto_Times[i]=...´´, mas poderá eventualmente usar ``Conjunto_Times[i][j]=...´´.
*/

/*
Depois de terminar de usar, não precisa se preocupar com o que fazer com o array. Assim que ele
sair de escopo, o programa automaticamente colocará a memória que estava ocupada pelo array
como liberada para outro uso.
*/


/* --- EXEMPLO COM ALOCAÇÃO DINÂMICA --- */

struct jogador **Conjunto_Times; /* Declaração: só ponteiro para ponteiro. Os ponteiros apontarão
para o primeiro elemento de cada nível de coleção, mas a memória
para a coleção de times e para cada coleção de jogadores só será
determinada mais à frente. */
int i;

/*
Antes de usar o conjunto de times, é preciso primeiro alocar espaço para os times e para os
jogadores de cada time.
*/

Conjunto_Times=malloc(20*sizeof(struct jogador *)); /* Aloca espaço para 20 coleções (note o "*" que
denota ponteiros) de jogadores (i.e. 20 times),
sendo que o espaço para os jogadores de cada
time só será alocado mais tarde. */
for(i=0; i<20; i++){
Conjunto_Times[i]=malloc(11*sizeof(struct jogador)); /* Aloca espaço para 11 jogadores (note que
aqui não há o "*") no (i+1)-ésimo elemento
da coleção de times (um elemento de uma
coleção de times é, obviamente, um time). */

/*
Depois de alocado o espaço para os times e para os jogadores de cada time, você pode usar
``Conjunto_Times[i][j]=...´´ de modo semelhante ao que podia fazer com os arrays.

Note que, agora, ``Conjunto_Times´´ _é_ uma variável (do tipo "ponteiro para ponteiro para struct
jogador"), de modo que o compilador não vai reclamar se você fizer ``Conjunto_Times=...´´ ou
``Conjunto_Times[i]=...´´ (aliás, nós mesmos usamos isso acima, na fase de alocação de espaço). Só
que você certamente NÃO VAI QUERER FAZER ISSO, pois se você alterar o valor do ponteiro criado por
malloc(), não terá como desalocá-lo depois.
*/

/*
Depois de terminar de usar ``Conjunto_Times´´, chegou a hora de desalocar o espaço que foi reservado
no início.
*/
for(i=0; i<20; i++)
free(Conjunto_Times[i]); /* Libera a memória reservada para os jogadores de cada time. */

free(Conjunto_Times); /* Libera a memória reservada para (os ponteiros para) cada time. */


3. Re: Alocação Dinâmica de matriz [RESOLVIDO]

Moises Viana Felipe
viana3

(usa openSUSE)

Enviado em 09/11/2013 - 17:19h

Muito obrigado pela explicação paulo1205, vou seguir a sua orientação.Apenas uma pergunta, no seu exemplo a struct aparece sem {} pode ser assim mesmo? Quanto ao nome dado ao vetor(Treze) foi inspirado no nome de um time de futebol do meu Estado.


4. Re: Alocação Dinâmica de matriz [RESOLVIDO]

Moises Viana Felipe
viana3

(usa openSUSE)

Enviado em 09/11/2013 - 18:00h

Paulo sem querer abusar da sua boa vontade, tenho mais algumas dúvidas.Para inserir os nomes dos times e jogadores, devo usar a forma
Conjunto_Times[i] ou Conjunto_Times[i][j]? 
A função que fará a leitura pode ser a scanf?


5. Re: Alocação Dinâmica de matriz [RESOLVIDO]

Paulo
paulo1205

(usa Ubuntu)

Enviado em 09/11/2013 - 22:17h

viana3 escreveu:

Muito obrigado pela explicação paulo1205, vou seguir a sua orientação.Apenas uma pergunta, no seu exemplo a struct aparece sem {} pode ser assim mesmo? Quanto ao nome dado ao vetor(Treze) foi inspirado no nome de um time de futebol do meu Estado.


Eu não me preocupei com a definição da estrutura, mas apenas assumi que já estava definida (do modo como você mesmo a definiu).

Só para lembrar, você define uma estrutura do seguinte modo.

struct some_struct {
int integer_field;
double double_field;
char string_field[40];
};


A definição acima cria o tipo de dados “struct some_struct”. Para declarar variáveis desse tipo, você simplesmente segue a regra padrão de colocar o nome do tipo antes do nome da nova variável (eventualmente com modificadores que permitem criar tipos derivados ponteiros, array, etc.).

struct some_struct var1, var2;  /* var1 e var2 são do tipo “struct some_struct”. */
struct some_struct *ptr1, *ptr2; /* ptr1 e ptr2 são ponteiros para um dado do tipo “struct some_struct”. */
struct some_struct arr1[10]; /* arr1 é um array com dez elementos do tipo “struct some_struct”. */







Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts