C++ – “Warning: Can’t find linker symbol for virtual table for value XXX value” using GCC and GDB (CodeBlocks)

c++gccgdbvirtual-functions

I'm getting a runtime error ("memory can't be written") that, after inspection through the debugger, leads to the warning in the tittle.

The headers are the following:

componente.h:

#ifndef COMPONENTE_H
#define COMPONENTE_H

using namespace std;

class componente
{
        int num_piezas;
        int codigo;
        char* proovedor;
    public:
        componente();
        componente(int a, int b, const char* c);
        virtual ~componente();
        virtual void print();

};

#endif // COMPONENTE_H

complement.h implementation

#include "Componente.h"
#include <string.h>
#include <iostream>

componente::componente()
{
    num_piezas = 0;
    codigo = 0;
    strcpy(proovedor, "");
    //ctor
}

componente::componente(int a = 0, int b = 0, const char* c = "")
{
    num_piezas = a;
    codigo = b;
    strcpy(proovedor, "");
}

componente::~componente()
{
    delete proovedor;//dtor
}

void componente::print()
{
    cout << "Proovedor: " << proovedor << endl;
    cout << "Piezas:    " << num_piezas << endl;
    cout << "Codigo:    " << codigo << endl;
}

teclado.h

#ifndef TECLADO_H
#define TECLADO_H

#include "Componente.h"


class teclado : public componente
{
        int teclas;
    public:
        teclado();
        teclado(int a, int b, int c, char* d);
        virtual ~teclado();
        void print();


};

#endif // TECLADO_H

teclado.h implementation

#include "teclado.h"
#include <iostream>

teclado::teclado() : componente()
{
    teclas = 0;//ctor
}

teclado::~teclado()
{
    teclas = 0;//dtor
}

teclado::teclado(int a = 0, int b = 0, int c = 0, char* d = "") : componente(a,b,d)
{
    teclas = c;
}

void teclado::print()
{
    cout << "Teclas: " << teclas << endl;
}

The main method where I get the runtime error is the following:

#include <iostream>
#include "teclado.h"

using namespace std;

int main()
{
    componente a; // here I have the breakpoint where I check this warning
    a.print();
    return 0;
}

BUT, if instead of creating an "componente" object, I create a "teclado" object, I don't get the runtime error. I STILL get the warning during debugging, but the program behaves as expected:

#include <iostream>
#include "teclado.h"

using namespace std;

int main()
{
    teclado a;
    a.print();
    return 0;
}

This returns "Teclas = 0" plus the "Press any key…" thing.

Do you have any idea why the linker is having troube with this? It doesn't show up when I invoke the virtual function, but before, during construction.

Best Solution

Two errors that I can see:

strcpy(proovedor, "");  // No memory has been allocated to `proovedor` and
                        // it is uninitialised.

As it is uninitialised this could be overwriting anywhere in the process memory, so could be corrupting the virtual table.

You could change this to (in both constructors):

proovedor = strdup("");

Destructor uses incorrect delete on proovedor:

delete proovedor; // should be delete[] proovedor

As this is C++ you should considering using std::string instead of char*.

If you do not change to std::string then you need to either:

  1. Implement a copy constructor and assignment operator as the default versions are incorrect if you have a member variable that is dynamically allocated, or
  2. Make the copy constructor and assignment operator private to make it impossible for them to be used.
Related Question