0
     *MyFile.h*

        typedef char* dado_t;
        typedef struct elemento elemento;
        typedef struct lista2 lista2;  

    *MyFile.c*

    struct elemento{
        dado_t str;
        elemento* ant;
        elemento* prox;
    };

    struct lista2{
        elemento* primeiro;
        elemento* ultimo;
        elemento* corrente;
    };

    void_insert(lista2* l, dado_t d){
       elemento* novo = malloc(sizeof(elemento*));
       novo->str = malloc(strlen(d) * sizeof(char));
       novo->str = d;
       l->corrente = novo;
       l->primeiro = novo;
       l->ultimo = novo;
       novo->prox = NULL;
       novo->ant = NULL;

    }

dado_t replace(lista2* l, dado_t d){
   dado_t retorno = malloc(strlen(corrente->str) * sizeof(dado_t));
   retorno = corrente->str;

   corrente->str = realloc(corrente->str, strlen(d) * sizeof(char));
   l->corrente->str = d;
   return retorno;
}

Why am I getting this error ? Since myel->str is a pointer that has been allocated with malloc(). Why the error ? I'm using an temporary element* to be prevented if an error happen with realloc()

Obs:

PlayHardGoPro
  • 2,791
  • 10
  • 51
  • 90
  • you have set `myel->str` to d after the malloc – Dinesh May 04 '15 at 23:37
  • @Dinesh Yes, but the error happens before the compiler gets there... =s – PlayHardGoPro May 04 '15 at 23:38
  • Do you want to share a little more of your code because calling sequence is unclear. perhaps - before realloc - just print myel->str and d - might give some clue – Dinesh May 04 '15 at 23:43
  • 2
    You cannot assign a string to `myel->str`, you must use `strcpy`. (And reserve space for the zero terminator in your `strlen` line!) – Jongware May 04 '15 at 23:44
  • @Jongware BINGO ! So stupid of me... Thanks guys =) – PlayHardGoPro May 04 '15 at 23:51
  • If you get it to work, don't hesitate to post the fixed code (or relevant snippet only) as an answer. That way others can see how to repair such an issue as well. – Jongware May 04 '15 at 23:54
  • 1
    @Jongware Isnt it better if you post the answer since you gave me that ? – PlayHardGoPro May 04 '15 at 23:55
  • there seems to be missing all the #include statements that are needed in myfile.c. I, personally, do not like reverse engineering someone elses' code to determine exactly what is missing. Please edit the code with the missing statements – user3629249 May 06 '15 at 01:30

3 Answers3

2

With elemento* novo = malloc(sizeof(elemento*)); you malloc only space for a pointer but then treat it as space for a struct. That overwrites book keeping information on the heap.

Peter - Reinstate Monica
  • 15,048
  • 4
  • 37
  • 62
1

The type dado_t is a char *, which initially points to nothing (I mean, not NULL but some random value). You correctly allocate some memory for it in

novo->str = malloc(strlen(d) * sizeof(char));

which has one tiny error: a C string of length d needs a single byte more memory for the terminating zero. So change this to

novo->str = malloc(strlen(d)+1);

Two notes here: sizeof(char) is guaranteed to be 1 (I think it's in the specifications; then again, it does no harm, and maybe you want to make sure you have the syntax right when allocating ints or other larger types).
Second, most standard libraries have a function that does exactly this: strdup. All you need to do is call it with your string address, it does the +1 part itself.

However, the next line is a more serious error:

novo->str = d;

In C you cannot "assign" one string to another this way. If you would want to do that, you would assign the address of one string to another. Which may lead to unforeseen problems, such as 'assigning' the address a constant string (which is valid but then you cannot modify it), or, worse, a string that is created inside a function on the 'local' stack.

In this case, you want to store a full copy of the string d from the function's argument, so you would use

strcpy (novo->str, d);

Do not forget that this pointer will be "lost" if you ever free the structure novo. A "lost" pointer is a block of memory that you allocated earlier (in the string malloc line) but no longer have a valid variable pointing to. So when freeing your elemento lists, call free(xx->str) first.

If you make sure that the str element is always set to NULL as soon as you create a new elemento structure, you can safely call free for the string even though it may be NULL; free can handle that. As it is, you seem to always assign a value, so it's not a case here, but in general I find it safe to explicitly clear out a newly created structure, for example with memset (novo, 0, sizeof(elemento));.

Community
  • 1
  • 1
Jongware
  • 22,200
  • 8
  • 54
  • 100
1

Peter Schneider has rightly pointed out that elemento* novo = malloc(sizeof(elemento*)) only allocates enough room for a pointer (because that’s what elemento* is); in this situation there are two common idioms, either of which does fine here:

  • elemento* novo = malloc(sizeof(elemento))
  • elemento* novo = malloc(sizeof(*novo))

And of course you need to take Jongware’s advice too!

PJTraill
  • 1,353
  • 12
  • 30