Do I need to re-allocate a structure in case I clean up just a part of it?

Asked

Viewed 80 times

2

I have a struct who owns nome and horário for appointments.

              typedef Struct{
               char nome[20];
               char data[20];
              }Dados;

I make the statement:

           Dados *dados_cliente[quantidade];

I make the allocation (whenever I start a new marking to not allocate everything):

         dados_cliente[i]=malloc(sizeof(Dados));

Now I’m working for the user to edit the markup, I could use an auxiliary structure but I preferred to do it this way:

        // SÓ VOU COLOCAR CASO ELE QUEIRA MUDAR O NOME PARA NÃO FICAR ENORME
        Case 1:
                free(dados_clientes[i]->nome);
                printf("DIGITE O NOVO NOME:\n);
                fflush(stdin);
                scanf("%[^\n]",dados_clientes[i]->nome);

Now my question, when I used the free() just in the name, do I need to allocate again? Or I should forget all this and use an auxiliary structure, and/or suggestions to solve it, if possible.

  • 2

    Are you mistaken in what the malloc and free mean. I advise you to start reviewing around, learning well what each one does and what the implications.

3 answers

3

There are a lot of problems in this code and even in the question, but I will focus on what you asked.

This free() does not do what you imagine. You can only give free() on something you’ve given malloc(), exactly the same thing, can’t invent something else to give free(). Could you just not have asked the question malloc() in the name, but I doubt it, and if you did it is wrong.

If the nome is a given inline in the structure does not have to allocate outside of it, so there is no need to give a malloc() for him, which I think you haven’t done. The die is already within the struct, if you allocate space for it, all space is already allocated, and if you need to free up space, it has to be done for the whole struct.

If you want to have the name with variable size and outside the struct so just put a pointer there and then allocate the name on demand, but that’s another problem, and we don’t have enough information to talk about it, actually this is even speculation.

  • Yes I used the structure, when I do a registration the dice are thrown to the structure (I did not put here not to get big the question), after I register a structure I wanted only if the user wants to make changes, if he wants to change the name I clear the name in the corresponding structure and make the change.

  • If possible point out the errors that you say you have in the code because I can’t see, I always used structures like this and it worked (using auxiliary structures) so I’m trying to find other ways to do it faster but I think there’s no way.

  • 3

    It is a lot and only with this information will not do much good. And I always posted here this: https://i.stack.Imgur.com/Cqixb.jpg. You are learning everything wrong because you believe that working means something, and especially in C means nothing useful. Working is the worst thing that can happen to you.

  • I ended up getting my words wrong, I beg your pardon, I know my programming is in the basics, I finished my first period of c at the end of last year, I just learned this way for allocating pointer structures, i allocate an entire structure and put free into it integer I wanted to delete it whole too, for changes I always used auxiliary structure, the user type what he wants to change and play to the auxiliary that passes(replaces) to the original structure, but I was trying to improve this way so I didn’t need to help.

1


In C, when there is a pointer, this points to the first byte of the memory related to that variable. When there is a static vector, the name of the vector without the brackets with an index is also treated as a pointer, pointing to the first byte vector memory. Therefore, when analyzing the type definition Dados

typedef struct{
    char nome[20];
    char data[20];
}Dados;

can be noticed that on a pointer to Dados, as dados_clientes[i], so much dados_clientes[i] how much dados_clientes[i]->nome point to the same memory address and so there is no segmentation failure in the command free(dados_clientes[i]->nome), but the whole structure is released, because it’s the same free(dados_clientes[i]).

To solve the problem, just delete the section free(dados_clientes[i]->nome);, for the member nome is static and therefore should not be released dynamically. Another possibility would be to use pointers for characters

typedef struct{
    char *nome;
    char *data;
}Dados;

In this way, however, it would be necessary to allocate memory dynamically to the members nome and data

  • Thank you very much, you understood my question and managed to answer!! Thankful.

0

    typedef struct
    {
        char nome[20]; 
        char data[20];
    }   Dados;

    Dados *dados_cliente[quantidade];

The name and date in its structure are strings, 20 bytes terminated by null. "Cleanse" a field like this can only be put a zero in the first position. No need to free up memory and re-allocate, and nor can because the way you wrote can only allocate a new structure in dados_cliente[i], where everyone is Dados*. If for example nome in dados_cliente[i] era "red" means there’s a zero after the 'the'. And you’ll trade yourself for "blue" just record 'a' z 'u' 'l' and '0' from dados_cliente[i][0];

dados_cliente is a fixed-size vector of pointers. And the pointers are possible targets of malloc() , free() and realloc(). And what can you "release" is what you allocate, in case the pointers, and one by one. You can start all with zero, the such NULL, and then release everyone. free() on a pointer NULL is harmless, but I imagine you keep track of how many of these quantidade pointers are in use.

If you want to allocate a variable number of these structures there is different, and you declare

Dados ** cadastro;

for example, and uses some logic to control allocation, like the one I described in an example yesterday right here in this post where you have a complete program, Or allocate one by one and use a linked list or some kind of structure like that. If you use a block of them you can iterate as in argv[i] in main(), using a pointer vector for structures, with the size given by quantidade, only variable, as in the case of the classic pair argc/argv of main()

Browser other questions tagged

You are not signed in. Login or sign up in order to post.