0

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?

levitopher
  • 117
  • 6
  • The fact that you consider the error message to be "useless" is a big clue to what you're missing. In other words, you're "missing" the information actually provided to you by the error message. :) – unwind Jun 19 '12 at 08:13
  • haha, I'm thinking of the word "useless" in the colloquial sense. I know a seg fault likely means some kind of invalid memory entry, which is useful information... but *more* useful information would be "(void *)smallest is not a valid pointer, you idiot!" – levitopher Jun 19 '12 at 18:24

3 Answers3

4

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));
caf
  • 233,326
  • 40
  • 323
  • 462
  • I appreciate it, even though it's a simple answer. I actually thought casting (void *) would copy the value in smallest to the memory pointed to by databuf. Shows I don't understand these things as well as I thought. Thanks! – levitopher Jun 19 '12 at 18:22
4
(void *)smallest

That takes the integer value of smallest and treats it as a pointer. What you meant to do was this:

(void *)&smallest
std''OrgnlDave
  • 3,912
  • 1
  • 25
  • 34
2

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?

David Schwartz
  • 179,497
  • 17
  • 214
  • 278