PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.c > realloc problem, corrupt last item
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
realloc problem, corrupt last item

Réponse
 
LinkBack Outils de la discussion
Vieux 08/05/2008, 15h15   #1
Igal
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut realloc problem, corrupt last item

hay, i have this werid problem with my book adding function, this how
it looks

book* AddBook(book *bp, unsigned *size) {
....
//then i use realloc to allocate space for the new item in the bp
pointer
bp = (book*)realloc(bp, sizeof(book));
....
}

when i do this, the next them is added in this right space. but let's
say *bp hold 2 book type items, first item will be ok, second one will
get garbage content, then the third item (the new reallocated one)
will get the new data.
i just have no idea will the last item gets corruped, this also
happens with more items in array.

i know that to use linked lists is a lot better solution, but i still
dunno how to use them right just yet.


  Réponse avec citation
Vieux 08/05/2008, 15h27   #2
Richard Heathfield
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: realloc problem, corrupt last item

Igal said:

> hay, i have this werid problem with my book adding function, this how
> it looks
>
> book* AddBook(book *bp, unsigned *size) {
> ...
> //then i use realloc to allocate space for the new item in the bp
> pointer
> bp = (book*)realloc(bp, sizeof(book));
> ...
> }


You have not provided sufficient information for me to you
effectively. On general principles, lose the cast, replace sizeof(book)
with sizeof *bp, use a temp to catch the result of realloc in case it
fails and returns NULL, and make sure you have #included <stdlib.h>. Note
that bp is a copy of the calling function's pointer; the original will not
be updated automatically, so if you want to keep the new value you must
provide a mechanism for the caller to assign this new value to the
original pointer.

For more specific , post more specific code. "..." doesn't say anything
useful, and you haven't shown the calling code.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
  Réponse avec citation
Vieux 08/05/2008, 15h33   #3
Igal
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: realloc problem, corrupt last item

> You have not provided sufficient information for me to you
> effectively. On general principles, lose the cast, replace sizeof(book)
> with sizeof *bp, use a temp to catch the result of realloc in case it
> fails and returns NULL, and make sure you have #included <stdlib.h>. Note
> that bp is a copy of the calling function's pointer; the original will not
> be updated automatically, so if you want to keep the new value you must
> provide a mechanism for the caller to assign this new value to the
> original pointer.


here's the full function.
i call it like this:

bp = AddBook(bp, &BOOK_SIZE);

/*#############################
# Add Book Function #
#############################*/
book* AddBook(book *bp, unsigned *size)
{
book temp;
unsigned n = *size; //n = size of book array
bool check = FALSE;
char str_cn[80];
int i;

printf("%d", (int)(sizeof(bp)/sizeof(bp[0])));

n++;
bp = (book*)realloc(bp, sizeof(book));
if (bp == NULL) { perror("ERROR [realloc - AddBook()]");
exit(ERR_REALOC); }


printf("\n[Add Book to Catalog]\n");

//get catalog number
while(check != TRUE)
{
printf("Book Catalog Number: ");
_flushall();
gets(str_cn);

//check if string is longer then 9 digits. if longer then error.
if(strlen(str_cn) > 9) { check = FALSE; printf("[E] catalog number
too long, 9 digit max.\n"); continue; }

//check each letter in string if a digit, if all are then check =
TRUE, else check = FALSE
i=0;
while(str_cn[i])
{
if(isdigit(str_cn[i])) { check = TRUE; i++; continue; }
else { check = FALSE; printf("[E] catalog number not valid, try
again.\n"); break; }
}

if(check == TRUE) { temp.cn = atol(str_cn); } //if all OK, put value
in str_cn
}
check = FALSE;

... here i get data into temp, and check validation ...

*size = n;

bp[n-1].cn = temp.cn;
bp[n-1].Units = temp.Units;
bp[n-1].Year = temp.Year;
bp[n-1].Price.CostPrice = temp.Price.CostPrice;
bp[n-1].Price.RetailPrice = temp.Price.RetailPrice;

strcpy(bp[n-1].Publisher, temp.Publisher);
strcpy(bp[n-1].BookName, temp.BookName);
strcpy(bp[n-1].Author.Author1, temp.Author.Author1);
strcpy(bp[n-1].Author.Author2, temp.Author.Author2);
strcpy(bp[n-1].Author.Author3, temp.Author.Author3);

return bp;
}
  Réponse avec citation
Vieux 08/05/2008, 15h36   #4
Jim Langston
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: realloc problem, corrupt last item

Igal wrote:
> hay, i have this werid problem with my book adding function, this how
> it looks
>
> book* AddBook(book *bp, unsigned *size) {
> ...
> //then i use realloc to allocate space for the new item in the bp
> pointer
> bp = (book*)realloc(bp, sizeof(book));


realloc accepts the pointer to the prevoiusly allocated block, and the new
size. Since you are passing sizeof( book ) you are only allocating enough
space for 1 item.

You probably meant something like:
bp = realloc( bp, sizeof( book ) * *size );
or
bp = realloc( bp, sizeof( book ) * (*size + 1) )
or something. I'm not sure how many additional items you want to allocate
for nor what size represents (new size or old size).

> ...
> }
>
> when i do this, the next them is added in this right space. but let's
> say *bp hold 2 book type items, first item will be ok, second one will
> get garbage content, then the third item (the new reallocated one)
> will get the new data.
> i just have no idea will the last item gets corruped, this also
> happens with more items in array.
>
> i know that to use linked lists is a lot better solution, but i still
> dunno how to use them right just yet.




--
Jim Langston
tazmaster@rocketmail.com


  Réponse avec citation
Vieux 08/05/2008, 15h37   #5
Igal
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: realloc problem, corrupt last item

> You have not provided sufficient information for me to you
> effectively. On general principles, lose the cast, replace sizeof(book)
> with sizeof *bp, use a temp to catch the result of realloc in case it
> fails and returns NULL, and make sure you have #included <stdlib.h>. Note
> that bp is a copy of the calling function's pointer; the original will not
> be updated automatically, so if you want to keep the new value you must
> provide a mechanism for the caller to assign this new value to the
> original pointer.


here's the full function.
i call it like this:

bp = AddBook(bp, &BOOK_SIZE);

/*#############################
# Add Book Function #
#############################*/
book* AddBook(book *bp, unsigned *size)
{
book temp;
unsigned n = *size; //n = size of book array
bool check = FALSE;
char str_cn[80];
int i;

n++;
bp = (book*)realloc(bp, sizeof(book));
if (bp == NULL) { perror("ERROR [realloc - AddBook()]");
exit(ERR_REALOC); }

.... here i get data into temp, and check validation ...

*size = n;

bp[n-1].cn = temp.cn;
bp[n-1].Units = temp.Units;
bp[n-1].Year = temp.Year;
bp[n-1].Price.CostPrice = temp.Price.CostPrice;
bp[n-1].Price.RetailPrice = temp.Price.RetailPrice;

strcpy(bp[n-1].Publisher, temp.Publisher);
strcpy(bp[n-1].BookName, temp.BookName);
strcpy(bp[n-1].Author.Author1, temp.Author.Author1);
strcpy(bp[n-1].Author.Author2, temp.Author.Author2);
strcpy(bp[n-1].Author.Author3, temp.Author.Author3);

return bp;
}
  Réponse avec citation
Vieux 08/05/2008, 15h43   #6
Igal
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: realloc problem, corrupt last item

On May 8, 5:36 pm, "Jim Langston" <tazmas...@rocketmail.com> wrote:
> Igal wrote:
> > hay, i have this werid problem with my book adding function, this how
> > it looks

>
> > book* AddBook(book *bp, unsigned *size) {
> > ...
> > //then i use realloc to allocate space for the new item in the bp
> > pointer
> > bp = (book*)realloc(bp, sizeof(book));

>
> realloc accepts the pointer to the prevoiusly allocated block, and the new
> size. Since you are passing sizeof( book ) you are only allocating enough
> space for 1 item.
>
> You probably meant something like:
> bp = realloc( bp, sizeof( book ) * *size );
> or
> bp = realloc( bp, sizeof( book ) * (*size + 1) )
> or something. I'm not sure how many additional items you want to allocate
> for nor what size represents (new size or old size).


in this function i need to reallocate only space for one new item.
*size is the number of items i have in my array.
correct me if i'm wrong, but if i realloc the size of my array+1,
won't this allocate + n items to the original array?


> Jim Langston
> tazmas...@rocketmail.com


  Réponse avec citation
Vieux 08/05/2008, 15h52   #7
Jim Langston
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: realloc problem, corrupt last item

Igal wrote:
>> You have not provided sufficient information for me to you
>> effectively. On general principles, lose the cast, replace
>> sizeof(book) with sizeof *bp, use a temp to catch the result of
>> realloc in case it fails and returns NULL, and make sure you have
>> #included <stdlib.h>. Note that bp is a copy of the calling
>> function's pointer; the original will not be updated automatically,
>> so if you want to keep the new value you must provide a mechanism
>> for the caller to assign this new value to the original pointer.

>
> here's the full function.
> i call it like this:
>
> bp = AddBook(bp, &BOOK_SIZE);
>
> /*#############################
> # Add Book Function #
> #############################*/
> book* AddBook(book *bp, unsigned *size)
> {
> book temp;
> unsigned n = *size; //n = size of book array
> bool check = FALSE;
> char str_cn[80];
> int i;
>
> printf("%d", (int)(sizeof(bp)/sizeof(bp[0])));


bp is a book*. Therefore, it's size is the size of a pointer (most likely 4
bytes). This is most likely not giving you what you want. You need to keep
track of the size for dynamically allocated arrays.

> n++;
> bp = (book*)realloc(bp, sizeof(book));


And here you are allocating space for *one* book. You need to allocate size
+ 1 (which is in n at this point) so this line should become:

bp = realloc( bp, sizeof(book) * n );

> if (bp == NULL) { perror("ERROR [realloc - AddBook()]");
> exit(ERR_REALOC); }
>
> printf("\n[Add Book to Catalog]\n");
>
> //get catalog number
> while(check != TRUE)
> {
> printf("Book Catalog Number: ");
> _flushall();
> gets(str_cn);
>
> //check if string is longer then 9 digits. if longer then error.
> if(strlen(str_cn) > 9) { check = FALSE; printf("[E] catalog number
> too long, 9 digit max.\n"); continue; }
>
> //check each letter in string if a digit, if all are then check =
> TRUE, else check = FALSE
> i=0;
> while(str_cn[i])
> {
> if(isdigit(str_cn[i])) { check = TRUE; i++; continue; }
> else { check = FALSE; printf("[E] catalog number not valid, try
> again.\n"); break; }
> }
>
> if(check == TRUE) { temp.cn = atol(str_cn); } //if all OK, put value
> in str_cn
> }
> check = FALSE;
>
> ... here i get data into temp, and check validation ...
>
> *size = n;
>
> bp[n-1].cn = temp.cn;
> bp[n-1].Units = temp.Units;
> bp[n-1].Year = temp.Year;
> bp[n-1].Price.CostPrice = temp.Price.CostPrice;
> bp[n-1].Price.RetailPrice = temp.Price.RetailPrice;
>
> strcpy(bp[n-1].Publisher, temp.Publisher);
> strcpy(bp[n-1].BookName, temp.BookName);
> strcpy(bp[n-1].Author.Author1, temp.Author.Author1);
> strcpy(bp[n-1].Author.Author2, temp.Author.Author2);
> strcpy(bp[n-1].Author.Author3, temp.Author.Author3);
>
> return bp;
> }


--
Jim Langston
tazmaster@rocketmail.com


  Réponse avec citation
Vieux 08/05/2008, 15h54   #8
Jim Langston
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: realloc problem, corrupt last item

Igal wrote:
> On May 8, 5:36 pm, "Jim Langston" <tazmas...@rocketmail.com> wrote:
>> Igal wrote:
>>> hay, i have this werid problem with my book adding function, this
>>> how it looks

>>
>>> book* AddBook(book *bp, unsigned *size) {
>>> ...
>>> //then i use realloc to allocate space for the new item in the bp
>>> pointer
>>> bp = (book*)realloc(bp, sizeof(book));

>>
>> realloc accepts the pointer to the prevoiusly allocated block, and
>> the new size. Since you are passing sizeof( book ) you are only
>> allocating enough space for 1 item.
>>
>> You probably meant something like:
>> bp = realloc( bp, sizeof( book ) * *size );
>> or
>> bp = realloc( bp, sizeof( book ) * (*size + 1) )
>> or something. I'm not sure how many additional items you want to
>> allocate for nor what size represents (new size or old size).

>
> in this function i need to reallocate only space for one new item.
> *size is the number of items i have in my array.
> correct me if i'm wrong, but if i realloc the size of my array+1,
> won't this allocate + n items to the original array?


No, realloc accpets the *new size* Total new size. How big you want the
array to be. Reguardless of how big it currently is. Which is current size
+ 1, or in your case (*size + 1) or with the source you gave before, n.

--
Jim Langston
tazmaster@rocketmail.com


  Réponse avec citation
Vieux 08/05/2008, 15h56   #9
Kenneth Brody
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: realloc problem, corrupt last item

Igal wrote:
[...]
> bp = (book*)realloc(bp, sizeof(book));


Here, you allocate room for one book.

I assume you really want:

bp = realloc(bp, sizeof(*bp) * n);

which will allocate room for n books.

[...]
> bp[n-1].cn = temp.cn;
> bp[n-1].Units = temp.Units;
> bp[n-1].Year = temp.Year;
> bp[n-1].Price.CostPrice = temp.Price.CostPrice;
> bp[n-1].Price.RetailPrice = temp.Price.RetailPrice;


Unless n==1, all of the above invoke UB by acessing memory
that does not belong to bp.

[...]

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:ThisIsASpamTrap@gmail.com>

  Réponse avec citation
Vieux 08/05/2008, 17h57   #10
K. Jennings
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: realloc problem, corrupt last item

On Thu, 08 May 2008 14:27:23 +0000, Richard Heathfield wrote:

> Igal said:
>
>> hay, i have this werid problem with my book adding function, this how
>> it looks
>>
>> book* AddBook(book *bp, unsigned *size) { ...
>> //then i use realloc to allocate space for the new item in the bp
>> pointer
>> bp = (book*)realloc(bp, sizeof(book)); ...
>> }

>
> You have not provided sufficient information for me to you
> effectively. On general principles, lose the cast, replace sizeof(book)
> with sizeof *bp,


Why? Under what circumstances they would not return the same
value?

  Réponse avec citation
Vieux 08/05/2008, 18h46   #11
Kenneth Brody
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: realloc problem, corrupt last item

"K. Jennings" wrote:
>
> On Thu, 08 May 2008 14:27:23 +0000, Richard Heathfield wrote:

[...]
> >> bp = (book*)realloc(bp, sizeof(book)); ...
> >> }

> >
> > You have not provided sufficient information for me to you
> > effectively. On general principles, lose the cast, replace sizeof(book)
> > with sizeof *bp,

>
> Why? Under what circumstances they would not return the same
> value?


In six months, when bp is changed to "book_v2 *". :-)

And, removing the unnecessary cast can uncover a hidden problem if
the proper header file isn't included.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:ThisIsASpamTrap@gmail.com>

  Réponse avec citation
Vieux 08/05/2008, 18h55   #12
Eric Sosman
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: realloc problem, corrupt last item

K. Jennings wrote:
> On Thu, 08 May 2008 14:27:23 +0000, Richard Heathfield wrote:
>
>> Igal said:
>>
>>> hay, i have this werid problem with my book adding function, this how
>>> it looks
>>>
>>> book* AddBook(book *bp, unsigned *size) { ...
>>> //then i use realloc to allocate space for the new item in the bp
>>> pointer
>>> bp = (book*)realloc(bp, sizeof(book)); ...
>>> }

>> You have not provided sufficient information for me to you
>> effectively. On general principles, lose the cast, replace sizeof(book)
>> with sizeof *bp,

>
> Why? Under what circumstances they would not return the same
> value?


When bp turns out not to be a book* but a book** or a
booklet* or a Book* or ...

Suppose that the compiler raises no objections to

ptr = malloc(sizeof(struct messagedetail));

Can you tell whether the malloc() call requests the correct
amount of memory for ptr to point at? Not until you scroll
around for a while to find the declaration of ptr to make
sure it's not a `struct messagedigest*' instead. But if
it's written as

ptr = malloc(sizeof *ptr);

.... you can tell at a glance that it's correct.

--
Eric.Sosman@sun.com
  Réponse avec citation
Vieux 08/05/2008, 23h17   #13
CBFalconer
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: realloc problem, corrupt last item

"K. Jennings" wrote:
> Richard Heathfield wrote:
>> Igal said:
>>

.... snip ...
>>
>>> book* AddBook(book *bp, unsigned *size) { ...
>>> // then i use realloc to allocate space for the new item in the
>>> // bp pointer
>>> bp = (book*)realloc(bp, sizeof(book)); ...

>>
>> You have not provided sufficient information for me to you
>> effectively. On general principles, lose the cast, replace
>> sizeof(book) with sizeof *bp,

>
> Why? Under what circumstances they would not return the same value?


Nor should you cast the output from realloc. It just hides error
messages. Also NEVER receive the result from realloc in the
original pointer. Create a temporary, and do:

if (tmp = realloc(bp, sizeof book) bp = tmp; /* ok, update */
else {
/* tmp == NULL, realloc failed, do whatever is needed */
/* Note that the original content of *bp still exists */
}

The above doesn not address problems with the 'sizeof book' that
you pass to realloc.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.


** Posted from http://www.teranews.com **
  Réponse avec citation
Vieux 09/05/2008, 06h32   #14
Richard Heathfield
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: realloc problem, corrupt last item

<snip>

I wrote:
"You have not provided sufficient information for me to you
effectively. On general principles, lose the cast, replace sizeof(book)
with sizeof *bp, use a temp to catch the result of realloc in case it
fails and returns NULL, and make sure you have #included <stdlib.h>. Note
that bp is a copy of the calling function's pointer; the original will not
be updated automatically, so if you want to keep the new value you must
provide a mechanism for the caller to assign this new value to the
original pointer."

The OP replied to the above, quoting a little of it, and then Chuck replied
to that reply:
> Nor should you cast the output from realloc. It just hides error
> messages. Also NEVER receive the result from realloc in the
> original pointer. Create a temporary, and do:
>
> if (tmp = realloc(bp, sizeof book) bp = tmp; /* ok, update */
> else {
> /* tmp == NULL, realloc failed, do whatever is needed */
> /* Note that the original content of *bp still exists */
> }
>
> The above doesn not address problems with the 'sizeof book' that
> you pass to realloc.


I'm curious to know what information Chuck thinks he added here.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
  Réponse avec citation
Vieux 09/05/2008, 10h52   #15
Antoninus Twink
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: realloc problem, corrupt last item

On 9 May 2008 at 5:32, Richard Heathfield wrote:
> The OP replied to the above, quoting a little of it, and then Chuck replied
> to that reply:
>>
>> if (tmp = realloc(bp, sizeof book) bp = tmp; /* ok, update */
>> else {
>> /* tmp == NULL, realloc failed, do whatever is needed */
>> /* Note that the original content of *bp still exists */
>> }

>
> I'm curious to know what information Chuck thinks he added here.


He added a syntax error in the if line, and gave the OP an example of
hideous C style: his idiotic inistence on one-line if statements that
makes code hard-to-read and debugging even harder, plus a completely
vacuous comment.

  Réponse avec citation
Vieux 09/05/2008, 10h54   #16
Eligiusz Narutowicz
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: realloc problem, corrupt last item

Antoninus Twink <nospam@nospam.invalid> writes:

> On 9 May 2008 at 5:32, Richard Heathfield wrote:
>> The OP replied to the above, quoting a little of it, and then Chuck replied
>> to that reply:
>>>
>>> if (tmp = realloc(bp, sizeof book) bp = tmp; /* ok, update */
>>> else {
>>> /* tmp == NULL, realloc failed, do whatever is needed */
>>> /* Note that the original content of *bp still exists */
>>> }

>>
>> I'm curious to know what information Chuck thinks he added here.

>
> He added a syntax error in the if line, and gave the OP an example of
> hideous C style: his idiotic inistence on one-line if statements that
> makes code hard-to-read and debugging even harder, plus a completely
> vacuous comment.


Does he really people? But I must be in agreement with you that
this style would not be allowed on my projects. It is horrible and very
amateur. Possibly Chuck is a new C programmer and learning though it is
better to be patient.

  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 21h24.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,27262 seconds with 24 queries