Mysterious segmentation fault in C++? - c++

I have been searching all over and cannot find anything like this. Now, I won't bore you with my whole program. It's incredibly long. But, here's your basic overview:
int main()
{
int i=0;
int h=5;
cout << "h(IS) = " << h << endl;
cout << "testing comment.";
while(i < 10)
{
cout << "I'm in the loop!";
i++;
}
return 0;
}
Looks great, right? Okay, so here's the problem. I run it, and I get a segmentation fault. The weirdest part is where I'm getting it. That testing comment doesn't even print. Oh, and if I comment out all the lines before the loop, I still get the fault.
So, here's my output, so you understand:
h(IS) = 5
Segmentation fault
I am completely, and utterly, perplexed. In my program, h calls a function - but commenting out both the line that prints h and the function call have no effect, in fact, all it does is give the segmentation fault where the line ABOVE the printing h line used to be.
What is causing this fault? Anything I can do to test where it's coming from?
Keep your answers simple please, I'm only a beginner compared to most people here :)
Note: I can provide my full code upon request, but it's 600 lines long.
EDIT: I have pasted the real code here: http://pastebin.com/FGNbQ2Ka
Forgive the weird comments all over the place - and the arrays. It's a school assignment and we have to use them, not pointers. The goal is to print out solutions to the 15-Puzzle. And it's 1 AM, so I'm not going to fix my annoyed comments throughout the thing.
I most recently got irritated and commented out the whole first printing just because I thought it was something in there...but no...it's not. I still get the fault. Just with nothing printed.
For those interested, my input information is 0 6 2 4 1 10 3 7 5 9 14 8 13 15 11 12
THANK YOU SO MUCH, EVERYONE WHO'S HELPING! :)

You slip over array boundaries, causing the corruption:
for (i=0; i<=4; i++)
{
for (j=0; j<=4; j++)
{
if (cur[i][j] == 0)
{
row = i;
col = j;
}
}
}
Your i and j indices must not reach 4.

valgrind is a great tool for debugging memory access problems. It's very easy to use on Linux. Just install G++ and valgrind, and then run (without the $ signs):
$ g++ -g -o prog prog.cpp
$ valgrind ./prog
It will print very detailed error messages about memory access problems, with source code line numbers. If those still don't make sense to you, please post the full source code (prog.cpp) and the full output of valgrind.
I've run valgrind for you, its output is here: http://pastebin.com/J13dSCjw
It seems that you use some values which you don't initialize:
==21408== Conditional jump or move depends on uninitialised value(s)
==21408== at 0x8048E9E: main (prog.cpp:61)
...
==21408== Conditional jump or move depends on uninitialised value(s)
==21408== at 0x804A809: zero(int (*) [4], int (*) [4], int*, int, int, int, int, int, int) (prog.cpp:410)
==21408== by 0x804A609: lowest(int (*) [4], int (*) [4], int, int, int, int, int, int) (prog.cpp:354)
==21408== by 0x804932C: main (prog.cpp:125)
...
To fix these problems, add code which initializes the variables depicted in the error lines above (e.g. line 61, 410), then recompile, and rerun with valgrind again, until all errors disappear.
If your program behaves weirdly even after fixing all problems reported by valgrind, please let us know.

Lines 57 - 67:
for (i=0; i<=4; i++)
{
for (j=0; j<=4; j++)
{
if (cur[i][j] == 0)
{
row = i;
col = j;
}
}
}
at least one of your errors is in this code, cur is declared int cur[4][4]; this means then when j==4 (and when i==4) you are not within the bounds of your array (well you are within the memory for some of them, but not all) valid values will be 0 - 3.

Related

C++ UndefinedBehaviorSanitizer:DEADLYSIGNAL [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I am trying to solve a problem for code wars, but my code gives an error. I've tested the code on code blocks and it works, but when I test it on their website it gives me some strange error. I looked it on the internet and found out that it might be a segmentation fault because of a deref of a null pointer, but I dont know how to fix it. This is my code and the error. Can you tell me plase what is the problem and why it works on code block, but on the compiler on the website it doesn't.(P.S. Please excuse my english, Im from Romania).
#include <iostream>
#include <vector>
#include <bits/stdc++.h>
using namespace std;
long queueTime(std::vector<int> costumers, int n) {
vector<int> q;
int j, x;
long t;
for (j = 0; j < n; j++)
q.push_back(costumers[j]);
int u = costumers.size();
while (j <= u) {
x = *min_element(q.begin(), q.end());
t = t + x;
for (int i = 0; i < n; i++) {
q[i] = q[i] - x;
if (q[i] == 0) {
q[i] = costumers[j];
j++;
}
}
}
t += *max_element(q.begin(), q.end());
return t;
}
Error message:
UndefinedBehaviorSanitizer:DEADLYSIGNAL
==1==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x000000000000 (pc 0x00000042547b bp 0x000000000000 sp 0x7ffec8fa0510 T1)
==1==The signal is caused by a READ memory access.
==1==Hint: address points to the zero page.
==1==WARNING: invalid path to external symbolizer!
==1==WARNING: Failed to use and restart external symbolizer!
#0 0x42547a (/workspace/test+0x42547a)
#1 0x427ffc (/workspace/test+0x427ffc)
#2 0x42686e (/workspace/test+0x42686e)
#3 0x426435 (/workspace/test+0x426435)
#4 0x42609b (/workspace/test+0x42609b)
#5 0x42aad5 (/workspace/test+0x42aad5)
#6 0x42581d (/workspace/test+0x42581d)
#7 0x7fc90f605b96 (/lib/x86_64-linux-gnu/libc.so.6+0x21b96)
#8 0x404489 (/workspace/test+0x404489)
UndefinedBehaviorSanitizer can not provide additional info.
==1==ABORTING
SEGV would indicate that there is a segmentation fault happening somewhere so you are on the right track with your debugging. Looking at the code you have provided there are few tips that might help you narrow down where things are going wrong.
The first thing that sticks out is that seem to be taking a local copy of costumers on this line:
for (j = 0; j < n; j++) q.push_back(costumers[j]);
Here you make the assumption that n is less or equal to costumers.size() and if n is larger than this then this will try to read from beyond the end of the vector. An alternative here is to use the = operator instead:
vector<int> q = costumers;
If you actually only wanted the first n elements of costumers copied to q then you could use:
if(n < q.size()){
q.resize(n);
}
to shrink it to size afterwards.
Another general style point is that it is good practice to something called "Resource allocation is initialization" (RAII): at the top of your queueTime function you have a bunch of variables declared but not initialized to values:
int j, x;
long t;
The problem here is that these will often be initialized to junk values and if you forget to initialize them later then you may be reading these junk values without knowing. Try instead to declare the variable at the point in the code you assign a value to it, eg fo j:
for(int j = 0; ... )
and x
int x = *min_element(q.begin(), q.end());
or in the case where you need t everywhere in the function scope, at least assign an initial value when you declare it
long t = 0;
Finally when using algorithms that return iterators it is generally good practice to check that they are valid before dereferencing them ie. writing:
auto itr_min_elem = min_element(q.begin(), q.end());
if(itr_min_elem == q.end()){
continue;
}
int x = *itr_min_elem;
so that if q is empty and min_element returns an end iterator then you don't try to dereference it.
Sorry for the wall of text but I hope these offer some help for debugging your function.
As a general note to your question about why it was working on code blocks but not on the website could come down to a number of reasons, likely related to how the code is being compiled. Some compilers will initialize memory to 0s in debug builds and this can have the effect of uninitialized variables behaving nicely in debug but in an undefined way in release. Also depending on the environment the code is executed in there may be differences in the memory layout so reading past the end of an array in one environment may just give junk while in another you may be indexing into protected memory or outside of your programs allocated memory. This would cause the platform running your code to be very unhappy and force it to abort.

A segmentation fault

I have try the following code to judge prime:
const int N = 200000;
long prime[N] = {0};
long num_prime = 0;
int is_not_prime[N]={1,1};
void Prime_sort(void)
{
for( long i = 2 ; i<N ; i++ )
{
if( !is_not_prime[i] )
{
prime[num_prime++] = i;
}
for( long j = 0; j<num_prime && i*prime[i]<N ; j++ )
{
is_not_prime[i*prime[j]] = 1;
}
}
}
But when I run it, it cause a segmentation fault! That fault I have never meet.And I searched Google,and it explain segmentation fault as follow:
A segmentation fault (often shortened to segfault) is a particular
error condition that can occur during the operation of computer
software. In short, a segmentation fault occurs when a program
attempts to access a memory location that it is not allowed to access,
or attempts to access a memory location in a way that is not allowed
But I don't know where cause this fault in my code.Please help me.
Your array is_not_prime has length N. For example, at the final lap of the outer for loop, i will have the value N-1. When i is that big, is_not_prime[i*prime[j]] will cause you to write far out of bounds of the array.
I'm not quite sure what j<num_prime && i*prime[i]<N is supposed to do, but it is likely part of the bug. Single step through the program with your debugger and see at what values the variables have when the program crashes.
Just re-write your program in a less complex manner and all bugs will go away.
Compare your loop bound checking to your indexing - they aren't the same. (I believe you meant to write i*prime[j]<N in your for loop.)
Your program crashes because an index goes out of bounds. And the index goes out of bounds because your algorithm is not valid.
As it still crashes if you set N at a much smaller value
const int N = 3;
it shouln't be too difficult to see what goes wrong by running your program with pencil and paper...

Why can array cells exceed array length [duplicate]

This question already has answers here:
Accessing an array out of bounds gives no error, why?
(18 answers)
Closed 7 years ago.
While debugging I found an error with an int array of 0. In a test document I messed around with array with more cell input than their length.
int array[0];
for(int i = 0; i < 10; i++)
array[i] = i;
for(int i = 0; i < 10; i++)
cout << array[i];
After I compiled and ran the program I got
0123456789
Then I received the message "test.exe has stopped working". I expected both of these, but what I am confused about is why the compiler lets me create an array of 0, and why the program doesn't crash until the very end of the program. I expected the program to crash once I exceeded the array length.
Can someone explain?
The compiler should have at least warned you about a zero size array - if it didn't .. consider changing compiler.
Remember that an array is just a bit of memory just like any other. In your example the array is probably stored on the stack and so writing off the end of it may not cause much of a problem until your function exits. At that point you may find you have written some text over the return address and you get an exception. Writing off the end of arrays are a common cause of bugs in C/C++ - just be thankful you got an error with this one and it didn't just overwrite some other unrelated data.

set a breakpoint in malloc_error_break to debug in C++

I'm writing a program that takes 2 command line arguments: a and b respectively.
Everything is good as long as a <= 17.5
As soon as a > 17.5 the program throws the following error:
incorrect checksum for freed object - object was probably modified after being freed
I've narrowed down the problem down to the following piece of code:
for(int a=0; a < viBrickWall.size(); a++) {
vector<int64_t> viTmp(iK-i);
fill(viTmp.begin(),viTmp.end(),2);
for(int b = 0; b < viBrickWall[a].size(); b++) {
viTmp[viBrickWall[a][b]] = 3;
}
viResult.push_back(viTmp);
viTmp.clear();
}
Removing the latter piece of code, gets rid of the error.
I'm also using valgrind to debug the memory, but I haven't been able to find any solution.
Here it is a copy of valgrind's report:
Report hosted in pastebin
EDIT
I compiled the program with debugging flags:
g++ -g -O0 -fno-inline program.cpp
and ran it with valgrind as follows:
` valgrind --leak-check=full --show-reachable=yes --dsymutil=yes ./a.out 48 10 ``
I noticed the following line:
==15318== Invalid write of size 8
==15318== at 0x100001719: iTileBricks(int) (test.cpp:74)
==15318== by 0x100001D7D: main (test.cpp:40)
Line 74 is:
viTmp[viBrickWall[a][b]] = 3;
and Line 40 is:
viBrickWall = iTileBricks(iPanelWidth);
You're causing an invalid write to heap memory with this line:
viTmp[viBrickWall[a][b]] = 3;
this implies that viBrickWall[a][b] is indexing outside of viTmp at that time. Add
int i = viBrickWall[a][b];
assert(0 <= i && i < viTmp.size());
before the store to viTmp[i] = 3.
HINT: maybe increasing the size of viTmp by one would fix it:
-vector<int64_t> viTmp(iK-i);
+vector<int64_t> viTmp(iK - i + 1);
I don't know the content of viBrickWall so this is just an educated guess from the Valgrind output.
I'm not sure if you're using GNU libstdc++ or libc++ on Mac OSX. If you're using libstdc++ or have a Linux box handy, declare viTmp to be a std::__debug::vector would catch this problem quickly.

Value Printed changes based on instructions that come after it

I appear to have coded a class that travels backwards in time. Allow me to explain:
I have a function, OrthogonalCamera::project(), that sets a matrix to a certain value. I then print out the value of that matrix, as such.
cam.project();
std::cout << "My Projection Matrix: " << std::endl << ProjectionMatrix::getMatrix() << std::endl;
cam.project() pushes a matrix onto ProjectionMatrix's stack (I am using the std::stack container), and ProjectionMatrix::getMatrix() just returns the stack's top element. If I run just this code, I get the following output:
2 0 0 0
0 7.7957 0 0
0 0 -0.001 0
-1 -1 -0.998 1
But if I run the code with these to lines after the std::cout call
float *foo = new float[16];
Mat4 fooMatrix = foo;
Then I get this output:
2 0 0 0
0 -2 0 0
0 0 -0.001 0
-1 1 -0.998 1
My question is the following: what could I possibly be doing such that code executed after I print a value changes the value being printed?
Some of the functions I'm using:
static void load(Mat4 &set)
{
if(ProjectionMatrix::matrices.size() > 0)
ProjectionMatrix::matrices.pop();
ProjectionMatrix::matrices.push(set);
}
static Mat4 &getMatrix()
{
return ProjectionMatrix::matrices.top();
}
and
void OrthogonalCamera::project()
{
Mat4 orthProjection = { { 2.0f / (this->r - this->l), 0, 0, -1 * ((this->r + this->l) / (this->r - this->l)) },
{ 0, 2.0f / (this->t - this->b), 0, -1 * ((this->t + this->b) / (this->t - this->b)) },
{ 0, 0, -2.0f / (this->farClip - this->nearClip), -1 * ((this->farClip + this->nearClip) / (this->farClip - this->nearClip)) },
{ 0, 0, 0, 1 } }; //this is apparently the projection matrix for an orthographic projection.
orthProjection = orthProjection.transpose();
ProjectionMatrix::load(orthProjection);
}
EDIT: whoever formatted my code, thank you. I'm not really too good with the formatting here, and it looks much nicer now :)
FURTHER EDIT: I have verified that the initialization of fooMatrix is running after I call std::cout.
UPTEENTH EDIT: Here is the function that initializes fooMatrix:
typedef Matrix<float, 4, 4> Mat4;
template<typename T, unsigned int rows, unsigned int cols>
Matrix<T, rows, cols>::Matrix(T *set)
{
this->matrixData = new T*[rows];
for (unsigned int i = 0; i < rows; i++)
{
this->matrixData[i] = new T[cols];
}
unsigned int counter = 0; //because I was too lazy to use set[(i * cols) + j]
for (unsigned int i = 0; i < rows; i++)
{
for (unsigned int j = 0; j < cols; j++)
{
this->matrixData[i][j] = set[counter];
counter++;
}
}
}
g64th EDIT: This isn't just an output problem. I actually have to use the value of the matrix elsewhere, and it's value aligns with the described behaviours (whether or not I print it).
TREE 3rd EDIT: Running it through the debugger gave me a yet again different value:
-7.559 0 0 0
0 -2 0 0
0 0 -0.001 0
1 1 -0.998 1
a(g64, g64)th EDIT: the problem does not exist compiling on linux. Just on Windows with MinGW. Could it be a compiler bug? That would make me sad.
FINAL EDIT: It works now. I don't know what I did, but it works. I've made sure I was using an up-to-date build that didn't have the code that ensures causality still functions, and it works. Thank you for helping me figure this out, stackoverflow community. As always you've been helpful and tolerant of my slowness. I'll by hypervigilant for any undefined behaviours or pointer screw-ups that can cause this unpredictability.
You're not writing your program instruction by instruction. You are describing its behavior to a C++ compiler, which then tries to express the same in machine code.
The compiler is allowed to reorder your code, as long as the observable behavior does not change.
In other words, the compiler is almost certainly reordering your code. So why does the observable behavior change?
Because your code exhibits undefined behavior.
Again, you are writing C++ code. C++ is a standard, a specification saying what the "meaning" of your code is. You're working under a contract that "As long as I, the programmer, write code that can be interpreted according to the C++ standard, then you, the compiler, will generate an executable whose behavior matches that of my source code".
If your code does anything not specified in this standard, then you have violated this contract. You have fed the compiler code whose behavior can not be interpreted according to the C++ standard. And then all bets are off. The compiler trusted you. It believed that you would fulfill the contract. It analyzed your code and generated an executable based on the assumption that you would write code that had a well-defined meaning. You did not, so the compiler was working under a false assumption. And then anything it builds on top of that assumption is also invalid.
Garbage in, garbage out. :)
Sadly, there's no easy way to pinpoint the error. You can carefully study ever piece of your code, or you can try stepping through the offending code in the debugger. Or break into the debugger at the point where the "wrong" value is seen, and study the disassembly and how you got there.
It's a pain, but that's undefined behavior for you. :)
Static analysis tools (Valgrind on Linux, and depending on your version of Visual Studio, the /analyze switch may or may not be available. Clang has a similar option built in) may help
What is your compiler? If you are compiling with gcc, try turning on thorough and verbose warnings. If you are using Visual Studio, set your warnings to /W4 and treat all warnings as errors.
Once you have done that and can still compile, if the bug still exists, then run the program through Valgrind. It is likely that at some point in your program, at an earlier point, you read past the end of some array and then write something. That something you write is overwriting what you're trying to print. Therefore, when you put more things on the stack, reading past the end of some array will put you in a completely different location in memory, so you are instead overwriting something else. Valgrind was made to catch stuff like that.