If this is your first visit, be sure to
check out the FAQ by clicking the
link above. You may have to register or Login
before you can post: click the register link above to proceed. To start viewing messages,
select the forum that you want to visit from the selection below.

I can't find anywhere that I would be overwriting the array bound, and everything runs perfectly until the program attempts to exit. Valgrind reports:

Code:

==5972== Invalid read of size 8
==5972== at 0x400A69: main (in /[path]/race)
==5972== Address 0x6fffffff8 is not stack'd, malloc'd or (recently) free'd
==5972==
==5972==
==5972== Process terminating with default action of signal 11 (SIGSEGV)
==5972== Access not within mapped region at address 0x6FFFFFFF8
==5972== at 0x400A69: main (in /[path]/race)
==5972== If you believe this happened as a result of a stack
==5972== overflow in your program's main thread (unlikely but
==5972== possible), you can try to increase the size of the
==5972== main thread stack using the --main-stacksize= flag.
==5972== The main thread stack size used in this run was 8388608.
==5972==
==5972== HEAP SUMMARY:
==5972== in use at exit: 0 bytes in 0 blocks
==5972== total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==5972==
==5972== All heap blocks were freed -- no leaks are possible
==5972==
==5972== For counts of detected and suppressed errors, rerun with: -v
==5972== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2)
Segmentation fault (core dumped)

I realize that using vectors instead of pointers would be the definative solution, but I'm a noob taking a C++ class and my assignment calls for use of char arrays and pointer passing. My environment is Linux Mint 13 using g++ 4.6.3-1 with default compile options (g++ file.cpp). I suspect I might be passing a bad array to cout, in that when I display the array positions returned by moveTortoise() and moveHare(), it doesn't seg fault on exit:

Re: Completely stumped by stack smash.

For some reason, I'm getting a segmentation fault when main() exits with the following code:

Mishandling pointers, buffer overrun, etc.

I realize that using vectors instead of pointers would be the definative solution,

It would not be a definitive solution, since overstepping the boundaries of an array and overstepping the boundaries of a vector result in the same thing -- undefined behaviour.

The only thing that vector takes care of is handling dynamically allocated memory in the form of an array (which of course is a big advantage). However, if you go and try to access element, say 10, of a vector that only can hold 9 items, then you get the same types of bugs as if you used an array. Unless the vector has extra checking in some "debug" mode, then you're no better off.

Nowhere in your code do you check to see if those indices inside your arrays or offsets into your arrays are in-bounds. You can't do this by sight -- actually write the code to test for a boundary conditions. You could have just checked right when the functions are called to check if the values passed are valid. If you started to check your indices carefully when you run the program, then maybe you will find the error after debugging.

Where is the check to make sure that "start" and "start + 7" are in-bounds? I'm sure that you can't check this by sight -- the best way to know and to ensure it doesn't go over the edge is to write the code to test and adjust to make sure "start" is within bounds.

Re: Completely stumped by stack smash.

Originally Posted by Paul McKenzie

The only thing that vector takes care of is handling dynamically allocated memory in the form of an array (which of course is a big advantage). However, if you go and try to access element, say 10, of a vector that only can hold 9 items, then you get the same types of bugs as if you used an array. Unless the vector has extra checking in some "debug" mode, then you're no better off.

Or you switch to using the at() member function instead of overloaded operator[], but then you still have the problem, except that you might be able to recover from it (and avoid undefined behaviour), at the cost of checks that would be unnecessary if you ensured that you stay within the bounds.

Re: Completely stumped by stack smash.

Does the program fail every time it runs or just sometimes? I've tried it under Windows VS (only changing usleep) and it works OK. Also, in main I've put a loop around race(..) and let it run a few thousand times with a very small TICK_MS and it again works OK. I've added assertions for bounds checking and again it just works OK!

Just as an experiment, try replacing cout with printf(...) and see what happens.

Where is the check to make sure that "start" and "start + 7" are in-bounds? I'm sure that you can't check this by sight -- the best way to know and to ensure it doesn't go over the edge is to write the code to test and adjust to make sure "start" is within bounds.

Regards,

Paul McKenzie

That function was the first culprit that I looked at, but removing the function entirely gives the same crash. I check bounds on the parameters before they are passed to the function, which should limit start to a range of 2-61. These two lines should keep the memory fills in bounds:

Re: Completely stumped by stack smash.

Originally Posted by 2kaud

Does the program fail every time it runs or just sometimes? I've tried it under Windows VS (only changing usleep) and it works OK. Also, in main I've put a loop around race(..) and let it run a few thousand times with a very small TICK_MS and it again works OK. I've added assertions for bounds checking and again it just works OK!

Just as an experiment, try replacing cout with printf(...) and see what happens.

It crashes every time it runs. Looping around race() doesn't cause it to crash any earlier for me either -- it's always when main exits.

Changing the printf() gives the same segmentation fault in Linux. Oddly, I just compiled it in Visual Studio and the Windows executable was just fine for me too. It only seems to be the Linux compile that has issues. I tried compiling with -O0 to disable optimizations, but I get the same result (with albeit a larger binary).

I already turned the assignment in (quiting with exit(0); instead of return 0; to keep it from crashing), I'd mainly just like to figure out what is going wrong.

Re: Completely stumped by stack smash.

the part in red increment the pointer not the pointee. Curiously, your bound checking code hides the effect by silently correcting the position value in memory; in turn, this could give an invalid read/write from some protected memory area or could simply bite you later when the corrupted memory is accessed by something else ( in your case the program termination code ).

BTW, if you had used an "if()" instead of the "?:" operator it would have been easier to spot ...

What's wrong with writing this in a clear, unobfuscated manner, so that it is understood what is being done? You aren't saving any time writing things on one line like that, and to add to the confusion, throwing in the ternary operator into the whole mix. It doesn't cost anything to make things clear by writing 3 or 4 if-then statements.

I don't know what your goal was to write code this way, but a lot of people who do write like this believe they can outsmart the compiler by believing "one line means speed". Instead, as in your case, it did nothing except introduce bugs.

Re: Completely stumped by stack smash.

Originally Posted by Paul McKenzie

To add to what superbonzo discovered, why are you writing code like this anyway?
What's wrong with writing this in a clear, unobfuscated manner, so that it is understood what is being done? You aren't saving any time writing things on one line like that, and to add to the confusion, throwing in the ternary operator into the whole mix. It doesn't cost anything to make things clear by writing 3 or 4 if-then statements.

I don't know what your goal was to write code this way, but a lot of people who do write like this believe they can outsmart the compiler by believing "one line means speed". Instead, as in your case, it did nothing except introduce bugs.

Regards,

Paul McKenzie

I had actually never used the ternary operators before this assignment (and I agree with your assessment of how those lines are written). The prof had two requirements for the assignment -- design the program around the given prototypes and demonstrate using ? : syntax. I have no doubt I'll learn more hanging around forums like this than the class.

Re: Completely stumped by stack smash.

Originally Posted by Comintern

I had actually never used the ternary operators before this assignment (and I agree with your assessment of how those lines are written). The prof had two requirements for the assignment -- design the program around the given prototypes and demonstrate using ? : syntax.

The ternary operator used as you used it is highly discouraged. If anything, it should be used in a simple, clear manner -- a simple left hand side of the ?, and simple true/false conditions on the right side of the ?.

Not only is it hard to decipher what you wrote, the ternary operator used multiple times on one line is a precedence nightmare. Things you think are being done in some order are not being done.

I don't understand why professors think it's worthwhile to have students write obfuscated code like this -- those code lines would never pass a real code review, as the reviewer themselves would need to look up, down, and sideways at those lines, and probably have to run the code to be convinced it really works.

Re: Completely stumped by stack smash.

those code lines would never pass a real code review,

I Totally agree with Paul regarding this. Many, many years ago when I started out as a programmer my code was often rejected by reviewers because they couldn't easily understand it - not because it didn't work. I was writing obfuscated code like this because this is how I had been taught at University - indeed I had exam questions about rewriting code to be the shortest possible! Once I jetisoned this way of writing and started writing working code that was simple to read then I had no further problems with reviewers. If you ever go for a programming job interview and they ask you to write some code, producing code like this will not endear you to the interviewers! Your professor should read what Donald Knuth (a world renowed computer scientist) has to say about program readability.

Knuth says. ďAlgorithms are not made to be packaged
into black boxes, but kept readable so that anyone using the code can understand how it is meant to work.

A further thought on your code. If the function parameters had been better defined then the error with *position++ would have been picked up by the compiler. As you are passing parameters by value and only changing the data pointed to and not the value itself then a better function definition would be

Code:

void moveTortoise(int *const position)

This says that position is a const and cannot be changed (position is a const pointer to an int). So any attempt in the function code to change position (especially accidential!) would be caught by the complier and reported as an error. Bugs caught by the compiler are much easier to fix than having to debug code later.

With Microsoft VS I get: error C2166: l-value specifies const object if I use const in the function definitions using *position++ but no error using *position +=1

Re: Completely stumped by stack smash.

Originally Posted by 2kaud

A further thought on your code. If the function parameters had been better defined then the error with *position++ would have been picked up by the compiler. As you are passing parameters by value and only changing the data pointed to and not the value itself then a better function definition would be

Code:

void moveTortoise(int *const position)

Since the pointer is assumed to be non-NULL in the function anyway, it would be even better to use a reference.

Code:

void moveTortoise(int& position)

Cheers, D Drmmr

Please put [code][/code] tags around your code to preserve indentation and make it more readable.

As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky