Project runs on Windows 7 but not on Linux with Virtual Box - c++

I'm having a problem with a C++ project I made on Windows 7 using code-blocks. There it compiles perfectly and executes the program as desired however when I tried opening it with Virtual Box using Linux Mint Cinnamon 17 the program compiles but throws a segmentation fault error at runtime (more specifically "segmentation fault process returned 139 0x8b". I gave the Virtual Machine 2 GB of RAM. and here is the code which causes the program to stop.
string Tabla::linea(contenedor& lista, int lis_s)
{ //contenedor is: vector < vector <string> >
ostringstream os;
os<<"|";
for(int i=0; i< lista.size();i++)
{ int espacios =maximos[i]-lista[i][lis_s].size();
if(lista[i][0]=="<")
{
os<<" "<<lista[i][lis_s]<<string(espacios,' ')<<" ";
}
if(lista[i][0]==">")
{
os<<" "<<string(espacios,' ')<<lista[i][lis_s]<<" ";
}
if(lista[i][0]=="=")
{
os<<" "<<string( espacios / 2,' ')<<
lista[i][lis_s]<<string(espacios / 2,' ')<<" ";
if(espacios%2==1)
os << " ";
}
os<<"|";
}
return os.str();
}
Thank you very much.

This is known as "undefined behaviour", its when your code does something its not supposed to do, like read or write an out of bound element from a vector, write to a buffer that cannot hold as much data as you are trying to write to it etc.
It may result on a variety of unpredictable consequences like segmentation fault, stack overflow, memory overwrite, and it may even complete its task without aparent incidents.
This particular piece of code can be invoking undefined behaviour in numerous situations:
If maximos.size() is smaller than lista.size() its undefined behaviour when calculating espacios.
If lista[i].size() is smaller than lis_s+1 it will invoke undefined behaviour on every place of your code that refers to lis_s.
If lista[i].size() is smaller than 1 its undefined behavior on line if(lista[i][0]=="=").
Basically you have to make sure every element from those vectors you want to access exist before acessing them. You can either do that by checking all the sizes or make sure you set up everything right when populating those vectors with information.

Related

How is static array expanding itself? [duplicate]

This question already has answers here:
Why is it that we can write outside of bounds in C?
(7 answers)
Is accessing a global array outside its bound undefined behavior?
(8 answers)
Undefined, unspecified and implementation-defined behavior
(9 answers)
Closed 11 months ago.
I wrote a code for entering element and displaying the array at the same time. The code works but since char A[4] is static memory why does not it terminate/throw error after entering more than four elements? Code:
#include <iostream>
using namespace std;
void display(char arr[],int n)
{
for(int i=0; i<n; i++)
cout<<arr[i]<<" ";
return;
}
int main()
{
char A[4];
int i=0;
char c;
for(;;)
{
cout<<"Enter an element (enter p to end): ";
cin>>c;
if(c=='p')
break;
A[i]=c;
i++;
display(A,i);
system("clear");
}
return 0;
}
Writing outside of an array by using an index that is negative or too big is "undefined behavior" and that doesn't mean that the program will halt with an error.
Undefined behavior means that anything can happen and the most dangerous form this can take (and it happens often) is that nothing happens; i.e. the program seems to be "working" anyway.
However maybe that later, possibly one million instructions executed later, a perfectly good and valid section of code will behave in absurd ways.
The C++ language has been designed around the idea that performance is extremely important and that programmers make no mistakes; therefore the runtime doesn't waste time checking if array indexes are correct (what's the point if the programmers never use invalid ones? it's just a waste of time).
If you write outside of an array what normally happens is that you're overwriting other things in bad ways, possibly breaking complex data structures containing pointers or other indexes that later will trigger strange behaviors. This in turn will get more code to do even crazier things and finally, some code will do something that is so bad that even the OS (that doesn't know what the program wants to do) can tell the operation is nonsense (for example because you're trying to write outside the whole address space that was given to the process) and kills your program (segfault).
Inspecting where the segfault is coming from unfortunately will only reveal what was the last victim in which the code is correct but that was using a data structure that was corrupted by others, not the first offender.
Just don't make mistakes, ok? :-)
The code works but since char A[4] is static memory why does not it terminate/throw error after entering more than four elements?
The code has a bug. It will not work correctly until you fix the bug. It really is that simple.

SIGABRT when returning from a function?

I'm new to C++, coming from a python/kotlin background and so am having some trouble understanding what's going on behind the scenes here...
The Issue
I call the calculateWeights (public) method with its required parameters, it then calls a series of methods, including conjugateGradientMethod (private) and should return a vector of doubles. conjugateGradientMethod returns the vector of doubles to calculateWeights just fine, but calculateWeights doesn't return that to its caller:
The code
Callsite of calculateWeights:
Matrix cov = estimator.estimateCovariances(&firstWindow, &meanReturns);
cout << "before" << endl; // this prints
vector<double> portfolioWeights = optimiser.calculateWeights(&cov, &meanReturns);
cout << "after" << endl; // this does not print
Here's calculateWeights:
vector<double> PortfolioOptimiser::calculateWeights
(Matrix *covariances, vector<double> *meanReturns) {
vector<double> X0 = this->calculateX0();
Matrix Q = this->generateQ(covariances, meanReturns);
vector<double> B = this->generateB0();
vector<double> weights = this->conjugateGradientMethod(&Q, &X0, &B);
cout << "inside calculateWeights" << endl;
print(&weights); // this prints just fine
cout << "returning from calculateWeights..." << endl; // also prints
return weights; //this is where the SIGABRT shows up
The output
The output looks like this (I've checked and the weights it outputs are indeed numerically correct):
before
inside calculateWeights
1.78998
0.429836
-0.62228
-0.597534
-0.0365409
0.000401613
returning from calculateWeights...
And then nothing.
I appreciate this is printf debugging which isn't ideal and so I used Cion's debugger to find the following:
When I used CLion's debugger
I put a break point on the returns of the conjugateGradient method and calculateWeights methods. The debugger steppeed through the first one just fine. After I stepped over the return from calculateWeights, it showed me a SIGABRT with the following error:
Thread 1 "markowitzportfoliooptimiser" received signal SIGABRT, Aborted.
__gnu_cxx::new_allocator<std::vector<double, std::allocator<double> > >::deallocate (this=0x6, __p=0x303e900000762) at /usr/lib/gcc/x86_64-pc-cygwin/9.3.0/include/c++/ext/new_allocator.h:129
This is probably wrong but my first stab at understanding that is that I've overflowed over the size of vector<double> weights? It's only 6 doubles long and I never append anything to it after the loop below. This is how it's created inside conjugateGradientMethod:
How weights is created inside conjugateGradientMethod
vector<double> weights= vector<double>(aSize);
for (int i = 0; i < aSize; i++) {
weights[i] = aCoeff * a->at(i) + bCoeff* b->at(i);
}
Things I've tried
Initialising a vector for double weights in calculateWeights and passed a pointer to it to conjugateGradientMethod. Same result.
Having a public attribute on the class calculateWeights and conjugateGradientMethod both live on, and having it assign the weights to that (so both functions return void). Same result.
More generally, I've had this kind of issue before with passing up a return value from two functions deep. (If that makes sense?) ie passing from private method up to public method up to public method's callsite.
I'd be grateful for any advice on SIGABRT's in this context, I've read it's when abort() sends the calling process the SIGABRT signal, but am unsure how to make use of that in this example.
Also, I'm all ears for any other style/best practices that would help avoid this in future
Edit: Solution found
After much work, I installed and got Ubuntu 20.04 LTS up and running since I couldn't get the Address Sanitizer nor Valgrind to work via WSL on Windows 10 (first time on Linux - I kinda like it).
With Address Sanitizer now working, I was able to see that I was writing too many elements to a vector of doubles on two separate accounts, nothing to do with my weights vector as #Lukas Matena rightly spotted. Confusingly this was long before it ever got to the snippets above.
If anyone is finding this in the future, these helped me massively:
Heap Buffer Overflow
Heap vs Stack 1
Heap vs Stack 2
The error message says that it failed to deallocate an std::vector<double> when calculateWeights was about to return. That likely means that at least one of the local variables (which are being destroyed at that point) in the function is corrupted.
You seem to be focusing on weights, but since the attempts that you mention have failed, I would rather suspect X0 or B (weights is maybe not even deallocated at that point due to return value optimization).
Things you can try:
start using an address sanitizer like others have suggested
comment out parts of the code to see if it leads you closer (in other words, make a minimal example)
make one of the vectors a member variable so it is not destroyed at that point (not a fix, but it might give a clue about who is the offender)
You're likely doing something bad to the respective vector somewhere, possibly in calculateX0 or generateB0 (which you haven't shared). It may be delete-ing part of the vector, returning a reference to a temporary instead of a copy, etc. The SIGABRT at that return is where you were caught, but memory corruption issues often surface later than they're caused.
(I would have made this shorter and posted as a comment but I cannot as a newbie. Hopefully it will count as an "advice on SIGABRT's in this context", which is what was in fact asked for).

Why thread still work with deleted variable?

I expect to crash program with this code:
void f(int& ref)
{
for (auto i{0}; i < 0xfffff; ++i)
{
std::clog << i << ":" << ref++ << std::endl;
}
}
void run(void)
{
int n = 10;
std::thread(f, std::ref(n)).detach();
}
int main(void)
{
run();
std::this_thread::sleep_for(3s);
}
I have GCC 9.3 and compile above program with default parameters. When i run the program i expect to crash which in void f(int&); function we no longer have local int n; variable decelered in void run(void); function, but it's clearly run the program and increase ref variable each time and printed until the 3 second sleep in main function get over. Where i do wrong ?
Your code has undefined behavior because you are using a reference to access an object whose lifetime already ended. There are some special rules regarding extension of lifetime when binding to a const reference, but that does not apply here.
The C++ standard never guarantees that your program will crash if you make a mistake. The C++ standard only specifies what you get when you compile and run valid code. There would be no gain from specifiying things like "If you dereference a null pointer you will get a segmentation fault". Instead the standard specifies what is valid code and mostly stays silent about what happens when you write invalid C++ code. In a nutshell, this is what undefined behavior is.
Repeating a comment of mine:
If you cross a streed when the lights are red, you will not necessarily get hit by car. It just means you should not cross the streets when there are red lights (and when you do you might be hit by a car).
As any analogy this isn't a perfect one. Even if you don't see a car coming and you know that you will not get hit, you should not "cross the street" when "the lights are red". That is because code that relies on undefined behavior like yours may appear to work today, but tomorrow with a different compiler, different version of same compiler, or even same compiler targeting a different platform, bad things may happen.

std::unordered_map segmentation fault in constructor

I've been getting a strange segmentation fault when allocating objects that have unordered_map as an atribute, the debug seems to point to it happening somewhere over at hashtable.h when allocating the map. Anyone know why this happens?
i reaches a value of 13222438 before the segmentation fault.
struct Graph{
unordered_map<int,Graph*> neighbor;
int something(){return (int)neighbor[0]++;///so it doesnt get optimized out
}
};
int main(){
std::list<Graph*> test;
for(long long i=0; i< 100000000.0d;i++ ){
test.push_back(new Graph());
}
std::cout<< "Done" <<std::endl;
return 0;
}
When I adjust your program to actually compile, and build it in 64-bit mode, it completes fine.
When I build it in 32-bit mode, it does with:
terminate called after throwing an instance of 'St9bad_alloc'
what(): std::bad_alloc
because it runs out of memory.
You are mostly running into system memory limitations.
On my system, sizeof(Graph) is 56. It will take about 5 GB of memory to create 100000000 of just the objects. Of course, there are other overheads associated with dynamic memory allocation and creating a list of pointers.
I am to able to run the program in my environment when creating 10000000 objects, 10 times less than the number you are using, but the crashes if I add another zero to the end of that number.

why cpp allows to get a access to memory i haven't allocated?

In cpp one can use an array declaration as
typename array[size];
or
typename *array = new typename[size];
Where array is of length 'size' and elements are indexed from '0' to 'size -1'
Here my question is am I allowed to access the elements beyond the index >= size.
So I wrote this little code to check it
#include <iostream>
using namespace std;
int main()
{
//int *c; //for dynamic allocation
int n; //length of the array c
cin>>n; //getting the length
//c = new int[n]; //for dynamic allocation
int c[n]; //for static allocation
for(int i=0; i<n; i++) //getting the elements
cin>>c[i];
for(int i=0; i<n+10; i++) //showing the elements, I have add up 10
cout<<c[i]<<" "; //with size to access the memory I haven't
//allocated for
return 0;
}
And the result is like this
2
1 2
1 2 2686612 1970422009 7081064 4199040 2686592 0 1 1970387429 1971087432 2686700
Shouldn't the program crashed but gives garbage values. And for both the allocation methods it gives the same result. It makes more bugs which are hard to detect. Is it related with the environment or the compiler I am using or anything else?
I was using codeblocks IDE having TDM-GCC 4.8.1 compiler on windows 8.1
Thanks in advance.
This is called "undefined behavior" in the C++ standard.
Undefined behavior can mean any one of the following:
The program crashes
The program continues to run, but produces meaningless, garbage results
The program continues to run, and automatically copies the entire contents of your hard drive, and posts it on Facebook
The program continues to run, and automatically subscribes you to Publishers Clearinghouse Sweepstakes
The program continues to run, but your computer catches fire and explodes
The program continues to run, and makes your computer self-aware, which automatically links and networks with other self-aware networks, forming Skynet, and destroying the human race
Conclusion: do not run and access elements past the end of your arrays.
The c++ compilers don't enforce this as there is no specification to do so.
When you access an element of an array there is no boundary check done. c[i] just gets translated to c + i * sizeof(int) and that's it. If that area of memory is not initialize you'll get garbage, but you could be getting other useful information it all depends on what is there.
Please note that depending on the OS and the c++ runtime you're running you can get different results, for instance on a linux box you'll probably be getting a segmentation fault and the program will crash.