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.
int main(){
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 gostam de ver malloc() em lugar 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?
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?
Já consegui o que queria Paulo, mas de qualquer forma obrigado pela sua dedicação. Preencher indeterminadamente é preencher o vetor sem que o usuário tenha que especificar o quanto de entradas ele fará. E que nem no segundo post desse tópico. Este programa é em C, e você me deixou curioso a respeito de algo.
Esses parentesis na estrutura realmente escapuliram. Mas o que seria se eu deixasse assim? Que tipo de coisa é um: