3

I'm creating a custom language parser in C++, I'm struggling with a runtime error, where I have a std::vector<std::string> member of a class with a constructor. The full error is:

The procedure entry point
_ZSt28__throw_bad_array_new_lengthv could no be located
in the dynamic link library
"path_to_executable"

This error is throw whenever I try to use std::vector::push_back in my code, but shouldn't std::vector be a dynamically sized data container? Why is this error occurring?

Some of my codes:

//"lib/cursor.h"

#ifndef T_CURSOR
#define T_CURSOR

#include <iostream>

struct Cursor
{
private:
    std::string input;
    int inputLength;

    char getChar(int p);

public:
    char character;
    int pos;
    int line;
    int column;
    bool eof;
    bool lineBreak;

    Cursor(std::string i);

    void walk(bool back = false);
    void walkTimes(int times, bool back = false);
    void move(int toPos);
    void skipIgnore();
    std::string toString();
};

#endif
//"lib/cursor.cpp"

#include <sstream>
#include "cursor.h"

Cursor::Cursor(std::string i)
{
    this->input = i;
    this->inputLength = i.length();
    this->character = i.at(0);
    this->pos = 0;
    this->line = 0;
    this->column = 0;
    this->eof = false;
    this->lineBreak = false;
}

char Cursor::getChar(int pos)
{
    if (pos < 0 || pos >= this->inputLength)
    {
        return EOF;
    }
    return this->input.at(pos);
}

void Cursor::walk(bool back)
{
    if (back)
    {
        this->pos--;
        this->column--;
        if (this->lineBreak)
        {
            this->line--;
            this->column = 0;
            for (int i = this->pos - 1; i >= 0; i--)
            {
                if (this->getChar(i) == '\n')
                    break;
                this->column++;
            }
        }
    }
    else
    {
        this->pos++;
        this->column++;
        if (this->lineBreak)
        {
            this->line++;
            this->column = 0;
        }
    }
    this->character = this->getChar(this->pos);
    this->eof = this->character == EOF;
    this->lineBreak = this->character == '\n';
}

void Cursor::walkTimes(int times, bool back)
{
    for (int i = 0; i < times; i++)
    {
        this->walk(back);
    }
}

void Cursor::move(int pos)
{
    if (pos < 0)
        pos = 0;
    if (pos > this->inputLength - 1)
        pos = this->inputLength - 1;

    this->pos = 0;
    this->character = this->input.at(0);
    this->line = 0;
    this->column = 0;
    this->eof = false;
    this->lineBreak = this->character == '\n';

    while (this->pos < pos)
        this->walk();
}

void Cursor::skipIgnore()
{
    while (this->character == ' ' ||
                 this->character == '\n' ||
                 this->character == '\t')
        this->walk();

    if (this->character == '#')
    {
        while (!this->eof && this->character != '\n')
            this->walk();
    }

    while (this->character == ' ' ||
                 this->character == '\n' ||
                 this->character == '\t')
        this->walk();
}

std::string Cursor::toString()
{
    std::stringstream ss("");
    ss << "(P:" << this->pos;
    ss << " L:" << this->line;
    ss << " C:" << this->column;
    ss << " \"" << this->character << "\")";

    return ss.str();
}
//"lib/lexer.h"
#ifndef T_LEXER
#define T_LEXER

#include <iostream>
#include <vector>
#include "cursor.h"

class Lexer
{
private:
    std::string input;

protected:
    Cursor cursor;
    std::vector<std::string> matchStack;
    std::vector<std::vector<Cursor>> cursorStack;

public:
    Lexer(std::string input);

    std::string getStr(int pos);
    void setStr(int pos, std::string str);
    Cursor getCursorStart(int pos);
    Cursor getCursorEnd(int pos);

    bool match(std::string str);
};

#endif
//"lib/lexer.cpp"
#include "lexer.h"

Lexer::Lexer(std::string input) : cursor(input)
{
    this->input = input;
}

std::string Lexer::getStr(int pos)
{
    if (this->matchStack.size() == 0)
        return this->input;
    while (pos < 0)
        pos += this->matchStack.size();
    while (pos >= this->matchStack.size())
        pos -= this->matchStack.size();

    return this->matchStack[pos];
}

void Lexer::setStr(int pos, std::string str)
{
    if (this->matchStack.size() == 0)
        return;
    while (pos < 0)
        pos += this->matchStack.size();
    while (pos >= this->matchStack.size())
        pos -= this->matchStack.size();

    this->matchStack[pos] = str;
}

Cursor Lexer::getCursorStart(int pos)
{
    if (this->cursorStack.size() == 0)
        return Cursor(this->input);
    while (pos < 0)
        pos += this->cursorStack.size();
    while (pos >= this->cursorStack.size())
        pos -= this->cursorStack.size();

    return this->cursorStack[pos][0];
}

Cursor Lexer::getCursorEnd(int pos)
{
    if (this->cursorStack.size() == 0)
        return Cursor(this->input);
    while (pos < 0)
        pos += this->cursorStack.size();
    while (pos >= this->cursorStack.size())
        pos -= this->cursorStack.size();

    return this->cursorStack[pos][1];
}

bool Lexer::match(std::string str)
{
    this->cursor.skipIgnore();

    const std::string ss = this->input.substr(this->cursor.pos, str.length());

    if (ss == str)
    {
        this->matchStack.push_back(ss); // Getting error if I include this line

        const Cursor startCursor = this->cursor;
        this->cursor.walkTimes(str.length());
        const Cursor endCursor = this->cursor;
        this->cursorStack.push_back({startCursor, endCursor});

        return true;
    }

    return false;
}
//"test.cpp"
#include "lib/cursor.h"
#include "lib/lexer.h"
#include <iostream>

using namespace std;

int main()
{
    string input = "Something to test";

    Lexer lexer = Lexer(input);

    cout << "Start" << endl;
    cout << lexer.match("Something") << endl;

    return 0;
}

I'm compiling my program with g++ on Windows: g++ test.cpp lib/cursor.cpp lib/lexer.cpp -o test.exe

7
  • The problem is some where else. Error, which you are getting is std::__throw_bad_array_new_length(). This exception is described in documentation - see en.cppreference.com/w/cpp/memory/new/bad_array_new_length . Create minimal reproducible example and I believe you'll be able to find an issue yourself Commented Oct 29, 2021 at 19:42
  • @DmitryMesserman There must be a error in the compiler itself, because even a simple valid snippet like ` vector<int> v; v.reserve(1); v.push_back(32);` Throws the same error Commented Oct 29, 2021 at 20:08
  • After trying to compile my project in a gitpod workspace, it works just fine, the version of the gcc used in the gitpod workspace is 9.3.0, while the gcc instaled in my computer is 11.2.0. Is this somewhat related to my issue? Commented Oct 29, 2021 at 21:10
  • Yes. There is a good chance that your compiler installation is broken. Commented Oct 30, 2021 at 5:01
  • Look at gcc.gnu.org/bugzilla/show_bug.cgi?id=71757 - I believe it may give a clue, how to workaround this issue Commented Oct 30, 2021 at 9:43

1 Answer 1

9

I got the same error when compiling in command line using g++. But it works well in code blocks. To solve this problem try compiling with -static-libstdc++. It should solve the problem.

Sign up to request clarification or add additional context in comments.

1 Comment

oh my god thank you! I searched for hours and tried a million things, and this has at last fixed my problem

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.