Segmentation fault on vectors.

  • (4 Pages)
  • +
  • 1
  • 2
  • 3
  • Last »

53 Replies - 1159 Views - Last Post: 11 July 2019 - 02:24 PM Rate Topic: -----

#1 Xrey274   User is offline

  • D.I.C Regular

Reputation: 0
  • View blog
  • Posts: 282
  • Joined: 10-December 16

Segmentation fault on vectors.

Posted 24 June 2019 - 04:52 PM

Hi, just a little info before I start - I'm currently making a painting program with SFML and recently switched from Windows to Linux. Since I'm a genius I forgot to back up my main.cpp, which intern forced me to rewrite it. In the main.cpp is the main program loop where things are drawn to the screen. I rewrote most things, but forgot how I did the drawing of lines. It must have been some janky jerry-rigged way because I've been having trouble for days trying to fix it. Anyways rewrote a lot of the code of how lines are draw, but I am having a problem - the moment I click on the window(that is if I have selected the "Pen" tool) the program immeaditely crashes and a "Segmentation Fault" error shows up. I would be very glad if you could help me get this sorted out, a long with general advise on my code.

main.cpp(where lines are drawn
        for(int i = 0; i < resource.getDots().size(); ++i)
        {
        	window.draw(resource.getDots()[i]);
            window.draw(resource.getDots()[i].getConnectorLines()[i]);
        }

        for(int i = 0; i < resource.getSavedDots().size(); ++i)
        {
            for(int a = 0; a < resource.getSavedDots()[i].size(); ++i)
            {
            	window.draw(resource.getSavedDots()[i][a]);
                window.draw(resource.getSavedDots()[i][a].getConnectorLines()[a]);
            }
        }
    }


Now for where the press of click is handled:
void Resources::addDot(sf::Vector2f mouseCoords)
{
    FreeDraw newDot(mouseCoords, 30, r, g, B)/>/>/>;

    if(circles.size() >= 1)
    {
        newDot.addLine(circles[circles.size() - 2]);
    }
    
    dots.push_back(newDot);
}

void Resources::addSavedDots()
{
    savedDots.push_back(dots);

    dots.clear();
}



And finally this is the actual class of the Lines(it inherits from sf::CircleShape so it can be directly drawn):
#include "FreeDraw.h"
#include <cmath>

FreeDraw::FreeDraw(sf::Vector2f mousePos, float radius, int r, int b, int g)
{
    setRadius(radius);
    setOrigin(radius, radius);
    setPointCount(radius * 10);
    setPosition(mousePos);
    setFillColor(sf::Color(r, g, B)/>/>/>);
}

float pythagoreanTheorem(float a, float B)/>/>/>
{
    return sqrt((a * a) + (b * B)/>/>/>);
}

void FreeDraw::addLine(sf::CircleShape previousCircle)
{
    sf::RectangleShape line;

    line.setSize(sf::Vector2f(pythagoreanTheorem(getPosition().x - previousCircle.getPosition().x, getPosition().y - previousCircle.getPosition().y), previousCircle.getRadius() * 2));
    line.setOrigin(sf::Vector2f(0, line.getSize().y / 2));
    line.setPosition(previousCircle.getPosition().x, previousCircle.getPosition().y);

    //calculate arc-tangent
    double idk = atan2(getPosition().y - previousCircle.getPosition().y, getPosition().x - previousCircle.getPosition().x);

    //convert radians to degrees and set them as the rotation
    line.setRotation(idk * 180 / 3.14);

    line.setFillColor(previousCircle.getFillColor());

    connectorLines.push_back(line);
}

std::vector<sf::RectangleShape> FreeDraw::getConnectorLines()
{
    return connectorLines;
}



The dots and savedDots are just regular vectors that are in the .h file where the "click" of the mouse is processed. They look like this:

std::vector<FreeDraw> dots;
std::vector<std::vector<FreeDraw>> savedDots;

This post has been edited by Xrey274: 24 June 2019 - 04:58 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Segmentation fault on vectors.

#2 CTphpnwb   User is offline

  • D.I.C Lover
  • member icon

Reputation: 3822
  • View blog
  • Posts: 13,910
  • Joined: 08-August 08

Re: Segmentation fault on vectors.

Posted 24 June 2019 - 06:26 PM

#include <iostream>
#include <vector>
using namespace std;

void testOne(vector<int> vec) {
	cout << "testOne: "<< &vec[0] << endl;
}

void testTwo(vector<int> &vec) {
	cout << "testTwo: "<< &vec[0] << endl;
}

int main(int argc, const char * argv[]) {

	vector<int> testing;
	testing.push_back(10);
	testing.push_back(11);
	testing.push_back(12);

	testOne(testing);
	testTwo(testing);

	return 0;
}


My results:
testOne: 0x10214ebe0
testTwo: 0x10214e7c0


Why do you think the values are different?
Was This Post Helpful? 0
  • +
  • -

#3 Skydiver   User is online

  • Code herder
  • member icon

Reputation: 6966
  • View blog
  • Posts: 23,676
  • Joined: 05-May 12

Re: Segmentation fault on vectors.

Posted 24 June 2019 - 06:32 PM

I was just doing a cursory scan through your code. Here's an obvious out of bounds array access:
    if(circles.size() >= 1)
    {
        newDot.addLine(circles[circles.size() - 2]);
    }



When circles.size == 1, then cirles.size() - 2 will be -1.

And there is also this:
window.draw(resource.getDots()[i].getConnectorLines()[i]);



I know that your i loop ranges from 0 to getDots().size()-1, but are you guaranteed that each of your resource.getDots()[i].getConnectorLines() also has that exact same range?
Was This Post Helpful? 0
  • +
  • -

#4 Xrey274   User is offline

  • D.I.C Regular

Reputation: 0
  • View blog
  • Posts: 282
  • Joined: 10-December 16

Re: Segmentation fault on vectors.

Posted 25 June 2019 - 08:30 AM

CTphpnwb that would be because in TestOne the vector is passed reference, in TestTwo it's just copied. Problem is that even making them return by reference when the mouse moves(when a "connectorLine" is added and has to be drawn) the program crashes with segmentation fault.

getDots function:
std::vector<FreeDraw>& Resources::getDots()
{
    return dots;
}

std::vector<std::vector<FreeDraw>>& Resources::getSavedDots()
{
    return savedDots;
}



getConnectorLines function:
std::vector<sf::RectangleShape>& FreeDraw::getConnectorLines()
{
    return connectorLines;
}



As for skydiver - I fixed the first error that you found, also as for If I can guarantee it - yes I can. Since it repeats like this - dot, line, dot - I always know for a fact that there is 1 less lines than the amount of dots.

This is how I fixed the first issue:
    if(circles.size() >= 1)
    {
        newDot.addLine(circles[circles.size() - 1]);
    }



How I guarantee it:
if(i < resource.getDots().size() - 1)
            {
                window.draw(resource.getDots()[i].getConnectorLines()[i]);  
            }



Was This Post Helpful? 0
  • +
  • -

#5 Skydiver   User is online

  • Code herder
  • member icon

Reputation: 6966
  • View blog
  • Posts: 23,676
  • Joined: 05-May 12

Re: Segmentation fault on vectors.

Posted 25 June 2019 - 03:19 PM

Actually, it's the other way around, testOne() creates a brand new copy of the vector for use within the function, while testTwo() receives a reference to the vector so that it can modify the vector that was passed in to it.
Was This Post Helpful? 0
  • +
  • -

#6 Skydiver   User is online

  • Code herder
  • member icon

Reputation: 6966
  • View blog
  • Posts: 23,676
  • Joined: 05-May 12

Re: Segmentation fault on vectors.

Posted 25 June 2019 - 04:33 PM

Instead of us trying to guess where the segmentation fault is happening, why not simply run the program in a debugger? It will stop when the segmentation fault happens, and you can look at the call stack to see exactly where it is happening, and the current state of your variables that induced the problem.
Was This Post Helpful? 0
  • +
  • -

#7 Xrey274   User is offline

  • D.I.C Regular

Reputation: 0
  • View blog
  • Posts: 282
  • Joined: 10-December 16

Re: Segmentation fault on vectors.

Posted 25 June 2019 - 06:19 PM

Yeah my mistake I confused testOne and testTwo. I would use a debugger, but I have to setup an IDE which takes time. Will do tho.
Was This Post Helpful? 0
  • +
  • -

#8 Skydiver   User is online

  • Code herder
  • member icon

Reputation: 6966
  • View blog
  • Posts: 23,676
  • Joined: 05-May 12

Re: Segmentation fault on vectors.

Posted 25 June 2019 - 06:26 PM

You don't need an IDE. You simply need gdb. GNU Debugger or GDB: A Powerful Source Code Debugging tool for Linux Programs
Was This Post Helpful? 0
  • +
  • -

#9 Xrey274   User is offline

  • D.I.C Regular

Reputation: 0
  • View blog
  • Posts: 282
  • Joined: 10-December 16

Re: Segmentation fault on vectors.

Posted 25 June 2019 - 07:12 PM

It was kinda a pain in the butt, but I configured the IDE and ran some debugging. I haven't got a lot of information, but so far I know that vectors with vectors are the cause since drawing the connectorLines causes the segmentation fault along with drawing the savedDots which are saved in vectors inside another vector. And savedDots's connectorLines are like in like 3 vectors so they are just like the former 2. I also know that the error occurs at line 930 in stl_vector.h which by the comment left there allows for array like data access.

      /**
       *  @brief  Subscript access to the data contained in the %vector.
       *  @param __n The index of the element for which data should be
       *  accessed.
       *  @return  Read/write reference to data.
       *
       *  This operator allows for easy, array-style, data access.
       *  Note that data access with this operator is unchecked and
       *  out_of_range lookups are not defined. (For checked lookups
       *  see at().)
       */
      reference
      operator[](size_type __n) _GLIBCXX_NOEXCEPT
      {
	__glibcxx_requires_subscript(__n);
	return *(this->_M_impl._M_start + __n);
      }



IDE is not required, but really helps when doing debugging.

This post has been edited by Xrey274: 25 June 2019 - 07:12 PM

Was This Post Helpful? 0
  • +
  • -

#10 Skydiver   User is online

  • Code herder
  • member icon

Reputation: 6966
  • View blog
  • Posts: 23,676
  • Joined: 05-May 12

Re: Segmentation fault on vectors.

Posted 25 June 2019 - 07:36 PM

Yes, now go up the callstack and see where you are calling STL from your code. What index are you passing in as the index __n?
Was This Post Helpful? 0
  • +
  • -

#11 Skydiver   User is online

  • Code herder
  • member icon

Reputation: 6966
  • View blog
  • Posts: 23,676
  • Joined: 05-May 12

Re: Segmentation fault on vectors.

Posted 25 June 2019 - 07:45 PM

Or if you think that trying to use a debugger is way too much trouble, you could change all your code from using operator [] on vectors to using at(). For example replace:
myVector[i]

with
myVector.at(i)

It won't actually fix your code, but at least you will get an exception when you try to do an out of bounds array access. Some people can seem to wrap their heads around this concept more easily than the segmentation fault that happens when you really screw the pooch by accessing way out of bounds.

With the exception or the segmentation fault, you will still need to figure out why you are going out of bounds.
Was This Post Helpful? 0
  • +
  • -

#12 Xrey274   User is offline

  • D.I.C Regular

Reputation: 0
  • View blog
  • Posts: 282
  • Joined: 10-December 16

Re: Segmentation fault on vectors.

Posted 26 June 2019 - 12:18 AM

Sadly exceptions won't help me if I don't know what exactly causes them. I think I am going to put this away for some time as I have lost way too much sleep the past 2-3 days trying to figure it out. Advice and potential fixes are always welcome.
Was This Post Helpful? 0
  • +
  • -

#13 Skydiver   User is online

  • Code herder
  • member icon

Reputation: 6966
  • View blog
  • Posts: 23,676
  • Joined: 05-May 12

Re: Segmentation fault on vectors.

Posted 26 June 2019 - 05:37 AM

I suggest either using at() or using assert()s. Run your code in a debugger. When the exception gets thrown or the assert fires, the debugger will stop and there you have the smoking gun. There is no magic bullet that will stop you from having to perform the analysis at that point in time to try to figure out why you are passing an out-of-bounds value.

Although there is no magic bullet, here is one (of many) AC +5 programming techniques: Create and use unit tests. It is easier to create unit tests verify that your code works or handles cases for 0, 1, many, off-by-one, etc. Unit tests pay off. Once you create them, then you can keep running them each time you touch your code to make sure that you don't introduce a regression. If you find a bug later not covered by a unit test, then you add another unit test to induce that bug, then fix the bug. Now you've expanded your safety net to prevent regressions. I know how tempting it is to just write code and then run it, and then hope that the bugs will be easy to discover and fix while just playing with the product. Resist that temptation.
Was This Post Helpful? 0
  • +
  • -

#14 Skydiver   User is online

  • Code herder
  • member icon

Reputation: 6966
  • View blog
  • Posts: 23,676
  • Joined: 05-May 12

Re: Segmentation fault on vectors.

Posted 26 June 2019 - 06:24 AM

View PostXrey274, on 24 June 2019 - 07:52 PM, said:

... and recently switched from Windows to Linux. Since I'm a genius I forgot to back up my main.cpp, which intern forced me to rewrite it.

Source control is your friend. Use github. Use bitbucket. Use gitlab. Use Subversion or Perforce if you are not into these new distributed version control systems. Use something. (Use anything but Visual Source Safe. With VSS, you might as well throw your hard drive into a shredder. :)

Anyway, good luck with trying to rebuild this. You do know that sometimes it is easier to start from scratch? V2 and V3 re-writes for some reason actually come out to be cleaner designs.
Was This Post Helpful? 0
  • +
  • -

#15 Xrey274   User is offline

  • D.I.C Regular

Reputation: 0
  • View blog
  • Posts: 282
  • Joined: 10-December 16

Re: Segmentation fault on vectors.

Posted 26 June 2019 - 02:06 PM

I use Dropbox as my source control(for now at least) but just forgot to update the files there.
Was This Post Helpful? 0
  • +
  • -

  • (4 Pages)
  • +
  • 1
  • 2
  • 3
  • Last »