2

I'm trying to build 2 classes, one that creates a "function" object (Y = MX + B) and another that creates a Graph object, takes the function, and plots every Y value along the graph by inserting x values from -10 to 10 into the function. I have a loop which should take every Y value and place it along the graph, so long as it fits within the boundaries (the 2D vector is 21 elements tall and 21 elements wide). For some reason, when I try to actually replace the '-' char (that I have throughout the empty graph) with the '*' char, I get that error above.

Below is my Graph.cpp file.


// EDIT: Here is a MRE
#include <iostream>
#include <vector>
using namespace std;

class Graph
{
public:
    Graph();
    void displayGraph();
    Graph editGraph();
private:
    vector<vector<char>> yaxis;
    vector<char> line;
    vector<char> axis;
    
};

Graph::Graph()
{
    axis = {'_','_','_','_','_','_','_','_','_','_','|','_','_','_','_','_','_','_','_','_','_',};
    line = {'-','-','-','-','-','-','-','-','-','-','|','-','-','-','-','-','-','-','-','-','-'};
    yaxis = {line,line,line,line,line,line,line,line,line,line,axis,line,line,line,line,line,line,line,line,line,line};
}

void Graph::displayGraph()
{
    int i = 0;
    do
    {
        int z = 0;
        do
        {
            cout << yaxis[i][z];
            z++;
        }while(z < 20);
        cout << endl;
        i++;
    }while (i < yaxis.size());
}

Graph Graph::editGraph()
{
    Graph g1;
    int i = 0;
    int x = -10;
    int m1, b1;
    m1 = 2;
    b1 = 3;
    do
    {
        int yVal = (m1 * x) + b1;
        if((yVal + 10) >= 0 && (yVal + 10) <= 21)
        {
            g1.yaxis[(yVal+10)][i] = '*';
        }
        x++;
        i++;
    } while (i < 21);
    
    return g1;
}


int main()
{
    Graph g1;
    g1 = g1.editGraph();
    g1.displayGraph();
}

I tried placing breakpoints along the loop in the editGraph function, but for I just can't make sense of this specific error and what it means for my code. Is the problem the manner by which I'm inserting the new char? should I be using .at()? I've looked at other questions here with the same error, but they don't seem to be using vectors like I am.

user4581301
  • 33,082
  • 7
  • 33
  • 54
  • Someone somewhere marched out of allocated memory and into the weeds. `at` is a good suggestion, as would turning on whatever sanitizers are available in your tools. For example, `-fsanitize=address,undefined` in GCC- and GCC-like toolchains. – user4581301 May 08 '23 at 22:57
  • OK, so the sanitizer tells you exactly where the problem happened: https://godbolt.org/z/hjr98x8hE Not that helpful by itself. – user4581301 May 08 '23 at 23:10
  • No. Now that we know the data is stored in `vector`s, the rule of five is handled for you. That means `Graph` gets to happily be stupid and observe the rule of zero. – user4581301 May 08 '23 at 23:11
  • I'm sorry, I'm relatively new to programming and I'm having a hard time understanding what the sanitizer is saying. It's a memory issue? – bossmaster5402 May 08 '23 at 23:12
  • It's not giving any information that you didn't already have. `g1.yaxis[(yVal+10)][i] = '*';` goes out of bounds. Almost certainly `yVal+10` allows a bad value. – user4581301 May 08 '23 at 23:13
  • Ohhhh ok. That makes a lot of sense. Thank you. I did that because the graph I'm building goes from -10 to 10 on both axis, but the vectors start at 0. Is there a better way to make that adjustment? – bossmaster5402 May 08 '23 at 23:15
  • Usually when a program crashes in a debugger the debugger halts and allows you to investigate the crash site. Inspect `yVal` and see if it makes any sense. `(yVal + 10) <= 21` looks suspicious. – user4581301 May 08 '23 at 23:16
  • It worked! the issue was the "<= to 21". Upon changing that to just less than, rather than less than equal to, it ran and graphed the points. Thank you so much!! – bossmaster5402 May 08 '23 at 23:17
  • General rule of thumb: When you see a `<=` deciding whether or not an iteration should continue, stop and examine more closely. Because C++'s arrays and array-like Standard containers are origin 0, a `<=` is usually a bug. – user4581301 May 08 '23 at 23:19
  • Pretty good example code, by the way. Hard to make the example much smaller without already knowing what the problem was. – user4581301 May 08 '23 at 23:21
  • Reading the diagnostics in https://godbolt.org/z/hjr98x8hE . The first line says **heap-buffer-overflow**, which means a dynamic array went out of bounds. Parsing the top stack trace in we see that the last line of your code to run is line 55 `#1 0x404f10 in Graph::editGraph() /app/example.cpp:55` Line zero of the trace is inside `vector` and the vast majority of the time you can be sure the bug's not in a library used millions of times a day like `vector`. – user4581301 May 08 '23 at 23:30
  • The second stack trace is pretty much the same ting, but a bit more thorough, for the cases where the mistake is outside of the code you wrote. Then they give you a block of memory around where the overflow was detected. This is useful because sometimes you can see the array the program just waked out of, instantly telling you what went wrong and how. The last bit I'll admit to not understanding all of, but I'm sure it's damn useful to the folk who do understand it. – user4581301 May 08 '23 at 23:33

0 Answers0