我收到一个运行时错误(“无法写入内存”),在通过调试器检查后,会导致警告。
标题如下:
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实施
#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实施
#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;
}
我得到运行时错误的主要方法如下:
#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;
}
但是,如果不创建“componente”对象,我创建了一个“teclado”对象,我没有得到运行时错误。我仍然在调试期间收到警告,但程序的行为符合预期:
#include <iostream>
#include "teclado.h"
using namespace std;
int main()
{
teclado a;
a.print();
return 0;
}
这会返回“Teclas = 0”加上“按任意键......”的事情。
你知道链接器为什么会遇到麻烦吗?当我调用虚函数时,但在构造之前,它不显示。
答案 0 :(得分:10)
我可以看到两个错误:
strcpy(proovedor, ""); // No memory has been allocated to `proovedor` and
// it is uninitialised.
由于它未被初始化,这可能会覆盖进程内存中的任何位置,因此可能会破坏虚拟表。
您可以将其更改为(在两个构造函数中):
proovedor = strdup("");
析构函数在delete
上使用了错误的proovedor
:
delete proovedor; // should be delete[] proovedor
由于这是C ++,您应该考虑使用std::string
而不是char*
。
如果您不更改为std::string
,则需要:
答案 1 :(得分:1)
同一消息的另一个来源是gdb可能会被尚未初始化的变量搞糊涂。 (这回答了问题标题,但不是OP的问题,因为网络搜索让我在这里寻找答案。)
当然,你不应该有未初始化的变量,但在我的情况下,gdb尝试在声明/初始化之前显示函数局部变量。
今天我逐步介绍了另一个开发人员的gtest案例,每次调试器停止时,此消息都会被转储到输出。在这种情况下,有问题的变量在〜第245行声明,但是函数在第202行开始。每次我在这些行之间停止调试器时,我收到了消息。
我通过将变量声明移到函数顶部来处理这个问题。
供参考,我在QtCreator 4.1.0中使用gdb版本7.11.1进行测试,并使用g ++版本5.4.1进行编译