views:

109

answers:

5

Howdy,

I seem to be having trouble with the following function:

void OtherClass::copy_this( int index, MyClass &class_obj)
{
    if(index < MAX_index)
        class_obj = array_of_MyClass[index];
}

OtherClass maintains an array of MyClass objects, and I would like this function to copy a selected object out of the array into the provided class_obj.

When I run, the program has a segmentation fault when it reaches this function. Running it in gdb and looking at the backtrace reveals that when it hits the assignment line, execution jumps backwards almost 100 lines into the middle of a completely different function. The line it jumps to is:

temp_obj = array_of_MyClass[other_index]

And the relevant output from the gdb backtrace is:

#0  0x0000003c7ae7256c in memcpy () from /lib64/tls/libc.so.6
#1  0x000000000043264e in MyClass::operator= (this=0x4c0000004c, _ctor_arg=@0x7fbffd8228) at ../location.cpp:156
#2  0x0000000000432569 in OtherClass::copy_this (this=0x7fbffd8220, index=0, section=@0x4c0000004c) at ../location.cpp:254

Obviously it's the same type of operation, but why on earth would execution move like that? I have no longjumps, gotos, etc. anywhere in the program. I also do not have user-defined assignment operators, copy constructors, etc., so the "operator=" from the backtrace is puzzling.

Before anyone asks, no, I cannot post the whole code. (Sorry!) I realize that may make it impossible to identify my problem; if this is the case, just let me know.

Thanks in advance!


After running through it again and testing a couple of "simplest use" cases, it seems that the problem is actually introduced somewhere earlier in execution, so it's back to the drawing board for me. Thank you all for your help!

A: 

Is the index a valid one? I see that you compare with MAX_index, but is your array containing MAX_index, initialized elements? I am asking because, if you copy an invalid object, you have undefined (unpleasant) behavior like you described.

Another possibility (if not this one) is that it is the time to make a full rebuild. Either the debug information is corrupted, or the generated code is incomplete (due to whatever reasons during the build process).

Cătălin Pitiș
Well, this happens with an index of zero, and I know there's an object in array[0] before this function gets called. MAX_index and array_of_MyClass are actually both class objects of OtherClass. MAX_index is a counter incremented as objects are added to the array.I tried a full rebuild, to no effect. (Sadly.)
Nicole
A: 

Is the code compiled with optimiser flags? The optimiser can do very strange things to the flow of execution, including jumping from one function over to a completely unrelated function that just happens to have a snippet of code that does something the first function needs.

Marcelo Cantos
g++ -O0 -g3 -Wall -c
Nicole
A: 

the line you say execution jumps backwards from is an assignment to an object of class MyClass. This is why you see MyClass::operator= in your backtrace. You say you have no user defined assignment operators or copy constructors, so this would explain the memcpy() right above it in the backtrace, since that's the default implementation of copying (shallow copy.)

In this case I think it might be helpful to implement a copy constructor (for Myclass).

Regarding the segfault itself - how was the array initialized? what was in index 0 of the array? (which seems to have been used in the call)

Yoni H
That makes sense. I thought the default operator would be fine, as I just need a shallow copy. As far as the segfault, please see my answer to Catalin.
Nicole
A: 

You don't have them, but the compiler produces them anyway, which is what you called when ou used the = operator on it. What is most likely is that the default assignment operator is insufficient for MyClass, which is why it isn't working. Implement them explicitly and see if this solves the issue.

Without more source code, there's little more that can be recommended.

DeadMG
Understandable. I thought it might be a problem with the default assignment operator. I'll try an explicit implementation and see if that helps.
Nicole
A: 

Should've payed attention to a few more frames back, and I would have seen the answer.

The MyClass object I was trying to copy the data into had been initialized as a NULL pointer, which is where the error in memcpy() was coming from. ("Cannot access memory at address 0x0" -- d'oh!) Can't believe I missed that...

Thanks for your help -- I probably would've continued beating my head against a wall had I not tried out your solutions. Explicitly writing the assignment operator convinced me that the problem was elsewhere.

Gratia plena!

Nicole