memcpy Seg fault seemingly innoculous
-
15-06-2021 - |
Question
Got a seg fault from my memcpy that gdb can't give me anything else on (at least beyond the simple manner that I know how to use gdb...). This thing is deeply imbedded in some code using the Berkely DB; I have taken out the only lines that should be of any use.
void *databuf;
int smallest;
databuf=malloc(2*sizeof(int));
memset(databuf,0,2*sizeof(int));
/* This next line comes from the DB structures; key.data is a void*... */
smallest=*(int *)key.data;
memcpy(databuf,(void *)smallest,sizeof(int));
To confirm the variable smallest is correct, I can run gdb and get
(gdb) print smallest
$1 = 120321
The error I recieve (in gdb) is the useless
Program received signal SIGSEGV, Segmentation fault.
0x08048efa in main (argc=4, argv=0xbffff344) at index_DB-1.1.c:128
128 memcpy(databuf,(void *)smallest,sizeof(int));
(gdb) backtrace
#0 0x08048efa in main (argc=4, argv=0xbffff344) at index_DB-1.1.c:128
The reason I am doing this is mostly because I am bastardizing the Berkley DB tutorial, but also later I want to do
memcpy(databuf+len,(void *)largest,sizeof(int));
i.e. have a void pointer databuf with first byes the smallest integer and second bytes the largest integer. What am I missing?
Solution
In this step, you are interpreting the value in smallest
as a pointer:
memcpy(databuf,(void *)smallest,sizeof(int));
Since that value is almost certainly not a valid pointer, this is causing your segfault. Instead, you likely want:
memcpy(databuf, &smallest, sizeof smallest);
Unless you need smallest
for some other reason though, you can just copy directly from key.data
to to databuf
:
memcpy(databuf, key.data, sizeof(int));
OTHER TIPS
(void *)smallest
That takes the integer value of smallest and treats it as a pointer. What you meant to do was this:
(void *)&smallest
It's hard to tell what you're doing, considering the code is so awful, but this looks very suspicious:
memcpy(databuf,(void *)smallest,sizeof(int));
I believe smallest
contains normal integer data, not a pointer to anything. So why are you dereferencing it? It doesn't point to anything.
You might want:
memcpy(databuf,(void *) &smallest,sizeof(int));
Also, this is suspect:
smallest=*(int *)key.data;
Is smallest
guaranteed to be integer aligned?