Unix Programming - Problem with malloc and memcpy

This is Interesting: Free IT Magazines  
Home > Archive > Unix Programming > January 2004 > Problem with malloc and memcpy





You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

Author Problem with malloc and memcpy
Eric Enright

2004-01-23, 5:36 pm

Hello, I'm having a problem with malloc, memcpy and a struct that I just
can not figure out. This sort of simulates an STL vector push_back(), in
that it is a block of memory that grows as I add structs to it. I malloc
memory for the size of the records currently stored plus one (more
struct), copy the old data to the new memory area, then append the new
data into the remaining space. Afterwards, I run through the memory and
dump some data. The output I expect is this:

0: filler
1: fake num 1
2: fake num 2
3: fake num 3

However, the output I'm getting is this:

0: filler
1:
2:
3: fake num 3

It seems like not all of previous data is copied properly, though I can
not locate the problem. Could perhaps someone shed some insight into
this? Am I going about what I want to do wrong? I would really
appreciate any ideas.



/* note, most of this code is taken out of my larger program */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <err.h>

#include <sys/socket.h>

#define ITERN 3
#define IW_ESSID_MAX_SIZE 32

struct mystruct
{
int mode;
struct sockaddr addr;
int qual;
int max_qual;
float freq;
char essid[IW_ESSID_MAX_SIZE + 1];
char key[27];
};

int main(int argc, char *argv[])
{
int n;
struct mystruct s;
int *ptr, *tptr;

strcpy(s.essid, "filler");

for (n = 0; n < 1 + ITERN; n++)
{
if (n == 0)
{
ptr = malloc(sizeof(struct mystruct));
if (ptr == NULL)
err(EXIT_FAILURE, "malloc()");
memcpy(ptr, &s, sizeof(struct mystruct));
}
else
{
sprintf(s.essid, "fake num %d", n);

/* get room for previous records, plus this new one */
tptr = malloc(sizeof(struct mystruct) * (n + 1));
if (tptr == NULL)
err(EXIT_FAILURE, "malloc()");

/* copy the previous records and free */
memcpy(tptr,
ptr,
sizeof(struct mystruct) * n);
free(ptr);

/* append the new record and save the pointer */
memcpy(tptr + (sizeof(struct mystruct) * n),
&s,
sizeof(struct mystruct));
ptr = tptr;
}
}

for (n = 0; n < 1 + ITERN; n++)
{
memcpy(&s,
ptr + (sizeof(struct mystruct) * n),
sizeof(struct mystruct));
printf("%d: %s\n", n, s.essid);
}

free(ptr);
return 0;
}

--
Eric Enright /"\
sauronAtiptsoftDcom \ / ASCII Ribbon Campaign
X Against HTML E-Mail
Public Key: 0xBEDF636F / \
Robert Harris

2004-01-23, 5:36 pm

Eric Enright wrote:
quote:

> /* append the new record and save the pointer */
> memcpy(tptr + (sizeof(struct mystruct) * n),


tptr is defined as a (int *) but sizeof() is in char's so the resulting
address is (sizeof() * n) int's past tptr.
quote:

> &s,
> sizeof(struct mystruct));



If you define tptr as a (char *), it'll be OK.

Robert
Robert Harris

2004-01-23, 5:36 pm

Eric Enright wrote:
quote:

> /* append the new record and save the pointer */
> memcpy(tptr + (sizeof(struct mystruct) * n),


tptr is defined as a (int *) but sizeof() is in char's so the resulting
address is (sizeof() * n) int's past tptr.
quote:

> &s,
> sizeof(struct mystruct));



If you define tptr as a (char *), it'll be OK.

Robert
Fletcher Glenn

2004-01-23, 5:36 pm



Eric Enright wrote:
quote:

> Hello, I'm having a problem with malloc, memcpy and a struct that I just
> can not figure out. This sort of simulates an STL vector push_back(), in
> that it is a block of memory that grows as I add structs to it. I malloc
> memory for the size of the records currently stored plus one (more
> struct), copy the old data to the new memory area, then append the new
> data into the remaining space.



<snippedp>
quote:

> --
> Eric Enright /"\
> sauronAtiptsoftDcom \ / ASCII Ribbon Campaign
> X Against HTML E-Mail
> Public Key: 0xBEDF636F / \




Instead of doing all of this by yourself, why not look into using realloc()?

--

Fletcher Glenn


Eric Enright

2004-01-23, 5:36 pm

On Mon, 19 Jan 2004 17:55:37 +0000, Robert Harris wrote:
quote:

> Eric Enright wrote:
>
> tptr is defined as a (int *) but sizeof() is in char's so the resulting
> address is (sizeof() * n) int's past tptr.
>
> If you define tptr as a (char *), it'll be OK.



Thanks Robert, it's working fine now.

Also thanks to Fletcher. After playing with malloc and memcpy and not
being able to get it, I just _had_ to get it to work, because I couldn't
understand why it wasn't.. ;) I think I'll use realloc now anyway, since
I know what was wrong.

PS: Sorry about some code appended to my comment lines and double closing
braces, looks like it's about time to upgrade Pan..

Thanks again guys, I really appreciate it!

--
Eric Enright /"\
sauronAtiptsoftDcom \ / ASCII Ribbon Campaign
X Against HTML E-Mail
Public Key: 0xBEDF636F / \

Peter Shaggy Haywood

2004-01-23, 5:36 pm

Groovy hepcat Robert Harris was jivin' on Mon, 19 Jan 2004 17:55:37
+0000 in comp.unix.programmer.
Re: Problem with malloc and memcpy's a cool scene! Dig it!
quote:

>Eric Enright wrote:
>
>tptr is defined as a (int *) but sizeof() is in char's so the resulting
>address is (sizeof() * n) int's past tptr.
>
>If you define tptr as a (char *), it'll be OK.



Better still, make it a struct mystruct * and use tptr + n instead
of tptr + (sizeof(struct mystruct) * n). (BTW, the outer set of
parentheses in the latter expression is superfluous.) That will make
it all much clearer to anyone reading the code.

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
Sponsored Links






Free braindumps | Software forum | Database administration forum

Copyright 2003 - 2008 webservertalk.com