473,657 Members | 2,414 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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.
Jun 27 '08 #1
15 1993
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 help 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 help, 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
Jun 27 '08 #2
You have not provided sufficient information for me to help 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_c n) 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.CostPric e = temp.Price.Cost Price;
bp[n-1].Price.RetailPr ice = temp.Price.Reta ilPrice;

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

return bp;
}
Jun 27 '08 #3
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
ta*******@rocke tmail.com
Jun 27 '08 #4
You have not provided sufficient information for me to help 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.CostPric e = temp.Price.Cost Price;
bp[n-1].Price.RetailPr ice = temp.Price.Reta ilPrice;

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

return bp;
}
Jun 27 '08 #5
On May 8, 5:36 pm, "Jim Langston" <tazmas...@rock etmail.comwrote :
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...@rocke tmail.com
Jun 27 '08 #6
Igal wrote:
>You have not provided sufficient information for me to help 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_c n) 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.CostPric e = temp.Price.Cost Price;
bp[n-1].Price.RetailPr ice = temp.Price.Reta ilPrice;

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

return bp;
}
--
Jim Langston
ta*******@rocke tmail.com
Jun 27 '08 #7
Igal wrote:
On May 8, 5:36 pm, "Jim Langston" <tazmas...@rock etmail.comwrote :
>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
ta*******@rocke tmail.com
Jun 27 '08 #8
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.CostPric e = temp.Price.Cost Price;
bp[n-1].Price.RetailPr ice = temp.Price.Reta ilPrice;
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:Th***** ********@gmail. com>

Jun 27 '08 #9
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 help 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(s truct 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.

--
Er*********@sun .com
Jun 27 '08 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
4024
by: WL | last post by:
Hey, all. I'm creating an array of strings (char **argv style) on the fly, and using realloc to create string pointers, and malloc for the strings itself (if that makes any sense). I'm using the construct ptr = realloc(ptr, size); *ptr = malloc(string_length); strncpy(ptr, src, string_length); to call realloc() multiple times. This should be ok, right?
36
2811
by: Roy | last post by:
Hi all : My code below : #include <stdio.h> #include <string.h> #include <stdlib.h> char *cat(char *s, const char *t) { char *tmp;
86
4117
by: Walter Roberson | last post by:
If realloc() finds it necessary to move the memory block, then does it free() the previously allocated block? The C89 standard has some reference to undefined behaviour if one realloc()'s memory that was freed by realloc(), but the only way explicitly mentioned in the C89 standard to free memory via realloc() is to realloc() it down to 0 bytes. I had always assumed it would automatically free the previous memory, but is the behaviour...
18
2344
by: ifmusic | last post by:
I used to think that i knew to program in C but this problem is making me thing otherwise. i'm trying to do something trivial, i suppose. i have this struct: typedef struct{ int socket; char ip; }peers;
27
31360
by: Deephay | last post by:
Greetings all, I have a program that used the realloc() function to change the allocated size of a buffer, the program works with some arguments, but with some other arguments, it will show me the error message like: *** glibc detected *** realloc(): invalid next size: 0x0804c3a8 *** and then I inserted a perror("realloc") to see what happend, it says that:
16
4813
by: Martin Joergensen | last post by:
Hi, I wanted to try something which I think is a very good exercise... I read in data from the keyboard and store them in a structure. There's a pointer called "data_pointer" which I use to keep track on the structures... But it's a bit confusing - my program won't compile and I don't know what to do about the warnings/error messages. c:\documents and settings\dell\Desktop\test\main.c(5) : warning
3
2299
by: kj | last post by:
I am trying to diagnose a bug in my code, but I can't understand what's going on. I've narrowed things down to this: I have a function, say foo, whose signature looks something like: int foo( int w, int x, int y, int z, my_struct **results ) During its execution, foo initializes *results using calloc: ( *results ) = calloc( w+1, sizeof( my_struct ) );
29
7872
by: marvinla | last post by:
Hello! I'm a beginner in C, and I'm having trouble with a pointer-to-pointer reallocation. This piece of code works well, but Valkyrie warns some parts (pointed below), and is breaking my real code. #include <stdio.h> #include <stdlib.h>
6
2316
by: lithiumcat | last post by:
Hi, maybe you remember me, some time ago I asked about how to store an integer value into a void*, and I learned that doing pointer arithmetic yeilding a pointer outside of an object (except the one- after-last thingy) is undefined behaviour. Actually I was trying to associate a function pointer with a key, through an AVL tree that managed void* data. Function pointers can't be stored in void* (that is, the standard does not garantee...
0
8315
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8734
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
8508
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
6172
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5633
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4164
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4323
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2733
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1962
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.