Alocação verdadeiramente dinâmica [RESOLVIDO]

13. Re: Alocação verdadeiramente dinâmica [RESOLVIDO]

Matth
MattF

(usa Slackware)

Enviado em 07/06/2015 - 15:30h

paulo1205 escreveu:

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.


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?

  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?


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:
 struct coisa(){" implementações"}  




  


14. Re: Alocação verdadeiramente dinâmica [RESOLVIDO]

Thiago Henrique Hüpner
Thihup

(usa Manjaro Linux)

Enviado em 07/06/2015 - 16:17h


Esses parentesis na estrutura realmente escapuliram. Mas o que seria se eu deixasse assim? Que tipo de coisa é um:
 struct coisa(){" implementações"}  



Isso indica que é uma função que terá o retorno "struct", mas geraria erro de compilação, pois não estaria informado o tipo de "struct". Um exemplo disto:


#include <stdio.h>

struct Retangulo{
int x, y;
};

// Ok
struct Retangulo retornaRetangulo(int x, int y){
struct Retangulo rect;
rect.x = x;
rect.y = y;
return rect;
};

int main(void){

struct Retangulo rect;

rect = retornaRetangulo(10,20);

printf("Rect X: %d Y: %d\n",rect.x,rect.y);

return 0;
}



Espero ter ajudado

[]'s

T+

--

Programador encontrado morto na banheira cinco dias após ter sido dado como desaparecido. Junto a ele foi encontrado um shampoo com as seguintes instruções:

LAVAR;
ENXAGUAR;
REPETIR;




15. Re: Alocação verdadeiramente dinâmica [RESOLVIDO]

Matth
MattF

(usa Slackware)

Enviado em 07/06/2015 - 17:21h

Thihup escreveu:


Esses parentesis na estrutura realmente escapuliram. Mas o que seria se eu deixasse assim? Que tipo de coisa é um:
 struct coisa(){" implementações"}  



Isso indica que é uma função que terá o retorno "struct", mas geraria erro de compilação, pois não estaria informado o tipo de "struct". Um exemplo disto:


#include <stdio.h>

struct Retangulo{
int x, y;
};

// Ok
struct Retangulo retornaRetangulo(int x, int y){
struct Retangulo rect;
rect.x = x;
rect.y = y;
return rect;
};

int main(void){

struct Retangulo rect;

rect = retornaRetangulo(10,20);

printf("Rect X: %d Y: %d\n",rect.x,rect.y);

return 0;
}



Espero ter ajudado

[]'s

T+

--

Programador encontrado morto na banheira cinco dias após ter sido dado como desaparecido. Junto a ele foi encontrado um shampoo com as seguintes instruções:

LAVAR;
ENXAGUAR;
REPETIR;



Beleza! Valeu pelas respostas de todos!





01 02



Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts