paulo1205
(usa Ubuntu)
Enviado em 07/06/2015 - 07:41h
MattF escreveu:
Então gente fiz algum progresso. Consegui fazer tal estrutura que é teoricamente dinamicamente allocável. Mas não funciona. TEnho erros de segmentation fault e acho que não deve ser assim. Ai está:
typedef struct sObjeto(){
Não tenho ideia de por quê você colocou esses parênteses aí. Tire-os pois, na melhor das hipóteses, eles são inócuos e, na pior, transformam o tipo
obj numa outra coisa totalmente diferente de uma
struct sObjeto .
char tipo[10], cor[10];
int lados, arestas, faces;
}obj;
typedef struct sConjuntoObj(){
Idem.
obj lista[100]
char NomeDoConjunto[50]
}cjt;
int memcheck(cjt *p){ /
if(p == NULL){
printf(" Sem memoria !!!!\n ");
exit(0);
}
}
Sobre este pedaço:
- Acho um desperdício ter uma função que é um mero apelido para um
if . Seria menos ruim se você ao menos tivesse declarado a função com o atributo
inline .
- Por convenção o código de saída zero é usado para indicar que o programa executou com sucesso. Como você está abortando o programa por conta de um erro de alocação de memória, seria mais razoável usar um código de saída diferente de zero (geralmente
exit(1) é suficiente).
-
memcheck não é um nome muito adequado porque não descreve o que a função realmente faz. Algo como
assert_valid_ptr ou
abort_if_null seria melhor.
Essa declaração não está conforme o padrão do C. Ela deveria ser ou “
int main(void) ” ou “
int main(int argc, char **argv) ”. Se for C++, “
int main() ” é válido, e tem o mesmo sentido que tem a primeira forma em C.
int tam=0;
cjt * p1 = (cjt *)calloc(tam,sizeof(cjt)), *p2;
Essa atribuição no meio da declaração de múltiplas variáveis fica confusa de ler. Pior ainda porque a atribuição é com uma expressão não-constante, com chamada de função e conversão de tipo. Simplifique isso, separando declaração e atribuição em linhas diferentes ou, pelo menos, movendo a variável que recebe a atribuição durante a declaração para o fim da linha.
Note ainda que, se você estiver usando C, a conversão de tipo é desnecessária e, por isso mesmo, não é vista com muito bons olhos por programadores mais experientes. Se, no entanto, você estiver usando C++, a conversão é necessária, mas os programadores experientes na linguagem não gostam de ver
malloc () em vez de
new , nem de ver
calloc () e
realloc () em lugar de
std::vector ().
Mais uma coisa, por sinal importante: veja o que diz o padrão do C, na seção que fala sobre as funções de alocação dinâmica:
If the size of the space requested is zero, the behavior is implementation-defined : either a null pointer is returned , or the behavior is as if the size were some nonzero value, except that the returned pointer shall not be used to access an object .
Uma boa prática, que você deve cultivar desde cedo, é não usar código cujo efeito real você desconhece ou que pode se comportar de modos diferentes dependendo do ambiente em que é implementado. No que diz respeito ao seu código, você deu sorte de não ter usado sua “
memcheck ()” com o valor inicial de
p1 , pois poderia ou não abortar o programa antes da realocação que vem logo em seguida.
Aliás, dado que logo em seguida você tem uma realocação de
p1 , por que usar aquele
calloc (), em vez de simplesmente
NULL ? Melhor ainda: se você sabe que vai crescer depois, por que não começar já com um tamanho não-nulo?
tam++;
p2 = (cjt *)realloc(p1,tam * sizeof(cjt));
memcheck(p2);
p1 = p2;
/*****E agora??***/
}
Como faço para preencher p1 dinamicamente e inderteminadamente com cada um dos campos da estrutura
?
Não sei se entendi sua dúvida. O que seria “preencher indeterminadamente”? A que estrutura você se refere, a
*p1 ou a cada elemento de
p1->lista ?