Reputation: 2923
*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:
Upvotes: 0
Views: 3110
Reputation: 1420
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!
Upvotes: 1
Reputation: 22447
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 int
s 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));
.
Upvotes: 1
Reputation: 16017
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.
Upvotes: 2