-
Why is it segfaulting?
I've reduced the code to something simple that still segfaults (for me at least) on the memcpy line. It does the same thing with strcpy. I'm using GCC 3.3 on Gentoo Linux.
Code:
char *funct( char *data, int bufsiz )
{
char *temp = malloc( sizeof( char ) * bufsiz + 1 );
temp[ bufsiz ] = '\0';
assert( temp != NULL );
memcpy( data, temp, bufsiz );
free( temp );
return data;
}
int main( void )
{
char *str = "hello world";
printf( "%s\n", funct( str, strlen( str ) ) );
return 0;
}
-
Because this
char *str = "hello world";
is a pointer to a static array. You cannot overwrite string literals (or at least you shoudln't).
Use
char str[] = "hello world";
What exactly are you trying to do in that function?
-
>XSquared
Aroo? I'm mildly confused about you writing this code XSquared. :P
>char *temp = malloc( sizeof( char ) * bufsiz + 1 );
sizeof ( char ) isn't needed, the size of a char is guaranteed to be 1. If you want to make sure that the argument to malloc is size_t then make bufsiz size_t. The sizeof only clutters the call.
>temp[ bufsiz ] = '\0';
>assert( temp != NULL );
Wrong order. Check first, then access. An assert isn't meant for run-time checking, it's meant for asserting impossible cases. malloc returning NULL is far from an impossible case.
>memcpy( data, temp, bufsiz );
You're writing the contents of temp (which are undefined except for the nul character at the end) to data. Your segfault is likely data being in read-only memory because it is a string literal, but this statement does nothing useful, and plenty undefined.
I say again, aroo?
-
>Wrong order. Check first, then access.
Those were just a couple of quick, butchered attempts to find the error.
>which are undefined except for the nul character at the end
There's a whole lot of processing which happens before the memcpy statement. I just tried to find the simplest case where it fails.
>the size of a char is guaranteed to be 1
Heh, ya learn something new every day.
-
> memcpy( data, temp, bufsiz );
Too little, and to the wrong place
memcpy( temp, data, bufsiz+1 );
You're overwriting your read-only string
-
>...and to the wrong place
I'm copying it to the right place. I'm overwriting data with temp.
I think you have the arguments to memcpy reversed. From the man pages:
Code:
MEMCPY(3) Linux Programmer's Manual MEMCPY(3)
NAME
memcpy - copy memory area
SYNOPSIS
#include <string.h>
void *memcpy(void *dest, const void *src, size_t n);
-
Code:
char *str = "hello world";
printf( "%s\n", funct( str, strlen( str ) ) );
No. You missed his point: You are trying to write over top of your read only string str. Your arguments are fine. What you're passing to it is not.
Quzah.
-
Sorry. I forgot that in the code here I still had it as a char *. I changed it to a char [] a while ago and it's been working fine.