C++ UndefinedBehaviorSanitizer:DEADLYSIGNAL [closed] - c++

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.

Related

Recursive code exits with exit code 3221225477

I am new to c++ programming and StackOverflow, but I have some experience with core Java. I wanted to participate in programming Olympiads and I choose c++ because c++ codes are generally faster than that of an equivalent Java code.
I was solving some problems involving recursion and DP at zonal level and I came across this question called Sequence game
But unfortunately my code doesn't seem to work. It exits with exit code 3221225477, but I can't make anything out of it. I remember Java did a much better job of pointing out my mistakes, but here in c++ I don't have a clue of what's happening. Here's the code btw,
#include <iostream>
#include <fstream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;
int N, minimum, maximum;
set <unsigned int> result;
vector <unsigned int> integers;
bool status = true;
void score(unsigned int b, unsigned int step)
{
if(step < N)
{
unsigned int subtracted;
unsigned int added = b + integers[step];
bool add_gate = (added <= maximum);
bool subtract_gate = (b <= integers[step]);
if (subtract_gate)
subtracted = b - integers[step];
subtract_gate = subtract_gate && (subtracted >= minimum);
if(add_gate && subtract_gate)
{
result.insert(added);
result.insert(subtracted);
score(added, step++);
score(subtracted, step++);
}
else if(!(add_gate) && !(subtract_gate))
{
status = false;
return;
}
else if(add_gate)
{
result.insert(added);
score(added, step++);
}
else if(subtract_gate)
{
result.insert(subtracted);
score(subtracted, step++);
}
}
else return;
}
int main()
{
ios_base::sync_with_stdio(false);
ifstream input("input.txt"); // attach to input file
streambuf *cinbuf = cin.rdbuf(); // save old cin buffer
cin.rdbuf(input.rdbuf()); // redirect cin to input.txt
ofstream output("output.txt"); // attach to output file
streambuf *coutbuf = cout.rdbuf(); // save old cout buffer
cout.rdbuf(output.rdbuf()); // redirect cout to output.txt
unsigned int b;
cin>>N>>b>>minimum>>maximum;
for(unsigned int i = 0; i < N; ++i)
cin>>integers[i];
score(b, 0);
set<unsigned int>::iterator iter = result.begin();
if(status)
cout<<*iter<<endl;
else
cout<<-1<<endl;
cin.rdbuf(cinbuf);
cout.rdbuf(coutbuf);
return 0;
}
(Note: I intentionally did not use typedef).
I compiled this code with mingw-w64 in a windows machine and here is the Output:
[Finished in 19.8s with exit code 3221225477] ...
Although I have an intel i5-8600, it took so much time to compile, much of the time was taken by the antivirus to scan my exe file, and even sometimes it keeps on compiling for long without any intervention from the anti-virus.
(Note: I did not use command line, instead I used used sublime text to compile it).
I even tried tdm-gcc, and again some other peculiar exit code came up. I even tried to run it on a Ubuntu machine, but unfortunately it couldn't find the output file. When I ran it on a Codechef Online IDE, even though it did not run properly, but the error message was less scarier than that of mingw's.
It said that there was a run-time error and "SIGSEGV" was displayed as an error code. Codechef states that
A SIGSEGV is an error(signal) caused by an invalid memory reference or
a segmentation fault. You are probably trying to access an array
element out of bounds or trying to use too much memory. Some of the
other causes of a segmentation fault are : Using uninitialized
pointers, dereference of NULL pointers, accessing memory that the
program doesn’t own.
It's been a few days that I am trying to solve this, and I am really frustrated by now. First when i started solving this problem I used c arrays, then changed to vectors and finally now to std::set, while hopping that it will solve the problem, but nothing worked. I tried a another dp problem, and again this was the case.
It would be great if someone help me figure out what's wrong in my code.
Thanks in advance.
3221225477 converted to hex is 0xC0000005, which stands for STATUS_ACCESS_VIOLATION, which means you tried to access (read, write or execute) invalid memory.
I remember Java did a much better job of pointing out my mistakes, but here in c++ I don't have a clue of what's happening.
When you run into your program crashing, you should run it under a debugger. Since you're running your code on Windows, I highly recommend Visual Studio 2017 Community Edition. If you ran your code under it, it would point exact line where the crash happens.
As for your crash itself, as PaulMcKenzie points out in the comment, you're indexing an empty vector, which makes std::cin write into out of bounds memory.
integers is a vector which is a dynamic contiguous array whose size is not known at compile time here. So when it is defined initially, it is empty. You need to insert into the vector. Change the following:
for(unsigned int i = 0; i < N; ++i)
cin>>integers[i];
to this:
int j;
for(unsigned int i = 0; i < N; ++i) {
cin>> j;
integers.push_back(j);
}
P.W's answer is correct, but an alternative to using push_back is to pre-allocate the vector after N is known. Then you can read from cin straight into the vector elements as before.
integers = vector<unsigned int>(N);
for (unsigned int i = 0; i < N; i++)
cin >> integers[i];
This method has the added advantage of only allocating memory for the vector once. The push_back method will reallocate if the underlying buffer fills up.

Segmentation fault occurs way after index leaves array boundary in C++ [duplicate]

This question already has an answer here:
will Index Out Of Array Bounds throw exception or error before core in C++?
(1 answer)
Closed 5 years ago.
I have this code:
#include <cstdio>
int foo[100];
int main()
{
for(int i=0;i<10000;i++)
foo[i]=10000;
}
Debugging with GDB gives a surprising result:
[New Thread 23684.0x59b4]
[New Thread 23684.0x5c0c]
[New Thread 23684.0x541c]
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401564 in main () at C:\Users\DARREN\Documents\Visual Studio
2017\Projects\Untitled1.cpp:9
warning: Source file is more recent than executable.
9 }
(gdb) print i
$1 = 4080
(gdb)
Now, I know the statement foo[i]=10000 caused the error, but I declared foo to be only of size 100. Why would the value of i be so big before the error occurs?
Any explanation is appreciated.
After you made an update to your question you posted this:
int foo[100];
int main()
{
for(int i=0;i<10000;i++)
foo[i]=10000;
}
And you are asking about segmentation fault.
Here you have an array with a size of 100 and you have a loop that ranges [0,9999] and within the for loop you are indexing the array with the for loops incremental variable i. When you step through the for loop for each iteration of i and you get to:
foo[i] = 10000;
when i <= 99 everything is okay.
What do you suppose happens when i >= 100?
When you use raw arrays there is no bounds checking; and this is something that you and the user will have to be responsible for. If you want automatic bounds checking done for you to prevent this out of bounds memory segmentation fault you should use any of the standard containers such as std::vector<T>, std::list<T>, std::set<T> etc. depending on your needs. If you need to use array index notation then std::vector<T> is the way to go. Or any other vector from any other library such as boost.
EDIT
For you to fix this problem you would have to either increase the size of the array from 100 to 10,000 or you would have to decrease your loop's condition from i<10000 to i<100 to accommodate for proper array indexing. Do not forget that C++ arrays have their starting index at 0 so you would have a basic array and loop as such:
int var[10]; // Uninitialized
for ( int i = 0; i < 10; ++i ) {
var[i] = 0; // Initialize all array indexes to 0
}
Notice that the condition in the for loop is i < 10 which is less than the actual size of the array when it is declared and not i <= 10 less than or equal to for this would also generate a segmentation fault or out of bounds error.

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.

C++: not getting segfaults when I should be [duplicate]

This question already has answers here:
Why doesn't this program segfault?
(1 answer)
Why doesn't this code cause a segfault?
(3 answers)
Closed 9 years ago.
I wrote the following after noticing something weird happening in another project. This code does not produce a segfault even though arrays are being called out of bounds multiple times. Can someone explain to me why there is no segfault from running the code below?
#include <stdlib.h>
#include <stdio.h>
int main()
{
int *a = (int *)malloc(4 * sizeof(int));
int *b = (int *)malloc(3 * sizeof(int));
int i = 0;
for(i =0; i <3 ; i++)
{
b[i] = 3+i;
}
for(i = 0; i < 4; i++)
{
a[i] = i;
}
for(i = 0; i < 100 ; i++){
a[i] = -1;
}
for(i = 0 ; i < 100 ; i++){
printf("%d \n", b[i]);
}
}
A segfault only happens if you try to access memory locations that are not mapped into your process.
The mallocs are taken from bigger chunks of preallocated memory that makes the heap. E.g. the system may make (or increase) the heap in 4K blocks, so reaching beyond the the bounds of your arrays will still be inside that block of heap-memory that is already allocated to your process (and from which it would assign memory for subsequent mallocs).
In a different situation (where more memory was allocated previously, so your mallocs are near the end of a heap block), this may segfault, but it is basically impossible to predict this (especially taking into account different platforms or compilers).
Undefined behaviour is undefined. Anything can happen, including the appearance of "correct" behaviour.
A segmentation fault occurs when a process tries to access memory which OS accounts as not belonging to the process. As memory accounting inside an OS is done by pages (usually 1 page = 4 KB), a process can access any memory within the allocated page without OS noticing it.
Should be using new and not malloc
What is the platform?
When you try undefined behaviour - gues what it is undefined.

GDB execution error : argc=<value temporarily unavailable, due to optimizations>, argv=0x7fff5fbff8f8

I've got a problem of execution with a C++ program. First of all, I'm working on a MacBook Pro, using native g++ to compile.
My program builds an array of Record*. Each record has a multidimensional key. Then it iterates over each record to find its unidimensional float key.
In the end, given an interval of two multidimensional keys, it determines if a given float corresponds to a multidimensional key in this interval. The algorithm is taken from a research paper, and it is quite simple in implementation.
Until 100,000 values computed, no problem, the program does its job. But when I goes to 1,000,000 values, execution crashes.Here is the error given by g++ :
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_PROTECTION_FAILURE at address: 0x00007fff5f08dcd0
0x00000001000021ab in TestPyramid () at include/indextree_test.cc:444
Here is the full backtrace given by gdb :
(gdb) backtrace full
#0 0x00000001000021ab in TestPyramid () at include/indextree_test.cc:444
test_records = #1 0x00000001000027be in main (argc=<value temporarily unavailable, due to optimizations>, argv=0x7fff5fbff8f8) at include/indextree_test.cc:83
rc = <value temporarily unavailable, due to optimizations>
progName = 0x7fff5fbff9f8 "/Users/Max/Documents/indextree_test"
testNum = 4
Given lines are calls to the function.
Here is a sample of code :
Record* test_records[1000000];
float values[1000000];
int base = 0;
for (int i(0); i < 1000000; i++)
{
test_records[i] = CreateRecordBasic(i%30+10,i+i%100,"ab","Generic Payload");
if (i%30+10 > base)
base = i%30+10;
if (i+10*i > base)
base = i+10*i;
if (i > base)
base = i;
}
for (int i(0); i < 1000000; i++)
values[i] = floatValueFromKey(test_records[i]->key, base,num_char);
And in the end, I put the relevant float keys in a list.
Is the problem a limitation of my computer ? Did I allocate the memory in a bad manner ?
Thanks for your help,
Max.
Edit :
Here is the code of CreateRecordBasic :
Record *CreateRecordBasic(int32_t attribute_1, int64_t attribute_2, const char* attribute_3, const char* payload){
Attribute** a = new Attribute*[3];
a[0] = ShortAttribute(attribute_1);
a[1] = IntAttribute(attribute_2);
a[2] = VarcharAttribute(attribute_3);
Record *record = new Record;
record->key.value = a;
record->key.attribute_count = 3;
SetValue(record->payload,payload);
return record;
}
Record* test_records[1000000];
float values[1000000];
IMHO, these variables are too big to be stored in the stack whose size is defined by your environment. values takes up 4 megabytes and test_records may take 4-8 megabytes, this is pretty big amount of stack-space. Compiler does not exactly know the size of the system-allocated stack (this may change from system to system) , so you get the error at run-time. Try to allocate them on the heap...