Passing an Object to Overloaded Operator
Asked Answered
M

3

7

Somebody gave me a a program having an error yesterday. Working in MVS 2010, I found the problem and an alternative for it as well. The problem was the overloaded insertion operator the class. Its prototype was as follows...

void matrix :: operator << (matrix&) ;

It was called from somewhere like this...

matrix m ;
m.operator << (m) ;

I worked out that compiler does not allow to send the same object as a reference parameter upon which the function was called. But I don't understand the reason behind that and that what problem does it create. I would appreciate if anybody could explain that. Thanks.

EDIT: What is actually happening is that upon debugging, it goes inside the function, comes out and at execution of main, goes into the external dependency file dbgdel.cpp and stops at this line.

 _ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
Macerate answered 12/9, 2012 at 14:46 Comment(12)
There's nothing wrong with the code as written, so the problem must be in the part that's not there. What is the problem?Babu
What compiler or runtime error did you get? Code you write must be careful to deal with self-reference and many programmers don't do that.Aloise
Do you have the code for the "void matrix :: operator << (matrix&)" and can modify or only execute ?Drain
The error was a runtime one. It took me to an external dependency file, i dont remember its name. And the problem was nowhere else, it was a pretty small program. Just changing the type of parameter fixed that.Macerate
Most likely you want const in there.Trabzon
Input is to be done inside the function. It cant be constMacerate
I just need to know that is there something in the standard which says that sending two objects to a function like this by reference creates some sort of shadowing, or some other problem?Macerate
@CodingMash: I think Ben Voigt meant the parameter should be const. Also, without the internals of the overloaded operator, there's not much we can do.Polybius
It does not make any sense to me. I think you guessed wrong on root of the cause. Even if that error comes up at the entry of the function, it may not mean that it is the cause. Look at code more widely around or post more code so we can see the context.Calends
It may have been possible. But after excluding and commenting out the whole code, the same error. Any Idea of the external dependency file where it takes after main execution?Macerate
@CodingMash At the risk of repeating what others said, I don't think there is anything in the Standard that disallows the code written above. But one possible cause of the problem comes to mind: If matrix is really a matrix, operator<< will probably iterate over the entries of the argument matrix and at the same time modify the contents, and possibly the number, of entries in the object matrix. Since both are identical objects, the iteration may fail as you add/remove entries to the data structure you are iterating over.Gauvin
Hmmm... That seems bit intelligent..Macerate
F
5

The code given compiles and runs just fine in VS2010 SP1.

There's no issue with the code as shown either, it's perfectly legal. I's a little odd to declare an operator overload and then call it with operator <<, as you could just as easily write m << m.

Some guesses:

  • You are taking the address of m somewhere in the operator implementation and accidentally deleting it
  • You are overrunning the boundaries of the array of values that is probably stored in the matrix, inside the operator implementation.
  • There's a mismatch in the compiler and linker assumptions between the calling code and the called code. Check your calling conventions, version of the runtime libraries on both sides, and any other settings such as SECURE_SCL and interator debugging.
Fox answered 14/9, 2012 at 14:58 Comment(4)
I've commented out the entire implementation as well. still the same error.Macerate
@CodingMash - long shot, is the matrix definition in a different DLL than the calling code?Fox
@CodingMash - okay, go over your project settings of the DLL and EXE with a fine-toothed comb and make sure they are calling the same version of the system libraries, and have the same iterator debugging settings.Fox
@CodingMash - I see you've accepted this answer, does that mean that different compiler or linker settings were the issue? Could you add some info here (edit the answer if you want) about the specific issue you discovered?Fox
A
1

In the method implementing the operator << make sure to check for self-reference:

void matrix :: operator << (matrix& other) 
{
  if (this == &other) 
  {
    /* special processing */
  }
 else
  {
    /* regular code */
  }
}
Aloise answered 12/9, 2012 at 15:0 Comment(2)
thats a separate thing. I want to know why it gave me error for sending the same object as a parameter.Macerate
As I said, the problem is in the code implementing operator<<, which is not expecting to have the same object passed as a parameter, and thus is manipulating internal structure in a way that generates the error.Aloise
P
1

Seems like your program is telling you the heap is corrupted: at some point it has gone over the bounds of an array or written to memory via a pointer that was freed, or something like that.

These bugs can be hard to track down, as you don't know exactly when it happened, but it is very likely it happened in a different place to where the error showed up. There is no problem with using reference parameters in the way you have.

There are a bunch of suggestions for how to detect heap corruption here:

Heap corruption under Win32; how to locate?

Pekan answered 16/9, 2012 at 7:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.