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. */