“操作符删除(void*)”的未定义引用

时间:2022-10-26 17:06:48

I'm new to C++ programming, but have been working in C and Java for a long time. I'm trying to do an interface-like hierarchy in some serial protocol I'm working on, and keep getting the error:

我是c++编程新手,但是我在C和Java工作了很长时间。我正在尝试在一些串行协议中做一个类似于接口的层次结构,并不断得到错误:

Undefined reference to 'operator delete(void*)'

The (simplified) code follows below:

(简化)代码如下:

PacketWriter.h:

PacketWriter.h:

class PacketWriter {
public:
    virtual ~PacketWriter() {}
    virtual uint8_t nextByte() = 0;
}

StringWriter.h:

StringWriter.h:

class StringWriter : public PacketWriter {
public:
    StringWriter(const char* message);
    virtual uint8_t nextByte();
}

The constructor and nextByte functions are implemented in StringWriter.cpp, but nothing else. I need to be able to delete a StringWriter from a pointer to a PacketWriter, and i've been getting various other similar errors if I define a destructor for StringWriter, virtual or not. I'm sure it's a simple issue that I'm overlooking as a newbie.

构造函数和nextByte函数在StringWriter中实现。cpp,但是什么都没有。我需要能够从一个指向PacketWriter的指针中删除一个StringWriter,如果我为StringWriter定义一个析构函数,不管它是否是虚拟的,我就会得到各种类似的错误。作为一个新手,我相信这是一个简单的问题。

Also, I'm writing this for an AVR chip, using avr-g++ on Windows.

另外,我写这是为了一个AVR芯片,在Windows上使用AVR -g+。

Thanks

谢谢

4 个解决方案

#1


13  

If you are not linking against the standard library for some reason (as may well be the case in an embedded scenario), you have to provide your own operators new and delete. In the simplest case, you could simply wrap malloc, or allocate memory from your own favourite source:

如果您没有因为某种原因而与标准库链接(在嵌入式场景中很可能是这种情况),那么您必须为自己的操作人员提供新的和删除操作。在最简单的情况下,您可以简单地包装malloc,或者从您自己最喜欢的源分配内存:

void * operator new(std::size_t n)
{
  void * const p = std::malloc(n);
  // handle p == 0
  return p;
}

void operator delete(void * p) // or delete(void *, std::size_t)
{
  std::free(p);
}

You should never have to do this if you are compiling for an ordinary, hosted platform, so if you do need to do this, you better be familiar with the intricacies of memory management on your platform.

如果您正在编译一个普通的托管平台,那么您不应该这样做,所以如果您确实需要这样做,您最好熟悉平台上复杂的内存管理。

#2


15  

Sorry for posting in an old thread, but it's still pretty high in Google's search results and if you have this problem, you really should check out this link, because there it says that you simply need to link -lstdc++ and this is what solved the problem for me.

很抱歉在一个旧的线程中发布,但是它在谷歌的搜索结果中仍然很高,如果你有这个问题,你真的应该检查这个链接,因为它说你只需要链接-lstdc++ ++,这就是我解决问题的方法。

The following line was added by the Community without highlighting it as such and instead of just adding a comment to my answer for reasons that elude me: "Or use a C++ compiler that will implicitly add the -lstdc++ option, e.g. g++."

下面的代码是社区添加的,没有高亮显示它,而不是仅仅添加一个注释来解释我的原因:“或者使用一个c++编译器,它将隐式地添加-lstdc++选项,例如g++。”

#3


9  

I will just quote the documentation, since they put it better.

我只引用文档,因为他们写得更好。

Writing C++

编写c++

You can write programs for the AVR platform in C++, if you included c++ in the enabled-languages during configuration of avr-gcc. Just about everything in the Writing C AVR programs section applies, so read that first.

如果在AVR -gcc的配置过程中,在启用语言中包含c++,那么可以用c++为AVR平台编写程序。几乎所有的写作C AVR程序部分都适用,所以先读一下。

The major drawbacks of using C++ are:

使用c++的主要缺点是:

C++ calling convention side-effects
No libstdc++ support.

C++ calling convention side-effects

c++调用协定的副作用

Certain C++ features will automatically generate implied code if required, which can waste valuable program memory space and processor time. For instance, if at some point in the program a function is passed a C++ object by value:

如果需要,某些c++特性将自动生成隐含代码,这会浪费宝贵的程序内存空间和处理器时间。例如,在程序中的某个点,函数通过值传递一个c++对象:

void myfunction(MyCppClass object);

You will wind up with a default copy constructor being generated and called to create the temporary copy of object used in myfunction(). Be careful if this isn't what you want: equivalent behavior should be attainable by passing a reference to a constant MyCppClass object, while avoiding the code and execution overhead.

最后生成并调用一个默认的复制构造函数来创建myfunction()中使用的对象的临时副本。如果这不是您想要的,那么要小心:通过引用一个常量MyCppClass对象来实现等效行为,同时避免代码和执行开销。

Missing libstdc++ and other C++ features

缺少libstdc++ +和其他c++特性

None of the C++ standard templates, classes or functions are available. In addition, operators new and delete have yet to be implemented.

没有任何c++标准模板、类或函数可用。此外,新的和删除操作符还没有实现。

C++ exception support is also lacking. You'll probably need to make sure to use the -fno-exceptions compiler option to turn off the exceptions in the C++ front-end.

还缺少c++异常支持。您可能需要确保使用-fno-exception编译器选项来关闭c++前端中的异常。

What does work? Even though lots of the C++ goodies you are accustomed to working with aren't available, it can be worthwhile to program the AVR in C++. Constructors and destructors are functional and just the organizational advantages of using classes and object oriented programming may make C++ a great choice.

工作什么?尽管您习惯使用的许多c++特性都不可用,但在c++中编写AVR程序是值得的。构造函数和析构函数是函数性的,仅仅使用类和面向对象编程的组织优势就可能使c++成为一个很好的选择。

#4


4  

If you're just looking to do an interface, you don't need new/delete. Just remove the "virtual" from the base class destructor, and make sure the derived class has an implementation of __cxa_pure_virtual().

如果你只是想做一个界面,你不需要新的/删除。只需从基类析构函数中删除“virtual”,并确保派生类具有__cxa_pure_virtual()的实现。

Here is a compilable example. (I removed the returns to keep things simple, but it works just fine with them.)

下面是一个可编译的示例。(我删除了退货以保持简单,但这对他们来说是没问题的。)

In PacketWriter.h

在PacketWriter.h

class PacketWriter {
public:
    virtual void nextByte() = 0;
protected:
    ~PacketWriter() {}
};

In StringWriter.h

在StringWriter.h

#include "PacketWriter.h"

class StringWriter : public PacketWriter {
public:
    StringWriter(const char* message);
    void nextByte();
};  

In StringWriter.cpp

在StringWriter.cpp

#include "StringWriter.h"

// Definition of the error function to call if the constructor goes bonkers
extern "C" void __cxa_pure_virtual() { while (1); }

StringWriter::StringWriter(const char* message)
{
    // constructor code here
}

void StringWriter::nextByte()
{
}

Compile with avr-g++ StringWriter.cpp

与avr-g + + StringWriter.cpp编译

#1


13  

If you are not linking against the standard library for some reason (as may well be the case in an embedded scenario), you have to provide your own operators new and delete. In the simplest case, you could simply wrap malloc, or allocate memory from your own favourite source:

如果您没有因为某种原因而与标准库链接(在嵌入式场景中很可能是这种情况),那么您必须为自己的操作人员提供新的和删除操作。在最简单的情况下,您可以简单地包装malloc,或者从您自己最喜欢的源分配内存:

void * operator new(std::size_t n)
{
  void * const p = std::malloc(n);
  // handle p == 0
  return p;
}

void operator delete(void * p) // or delete(void *, std::size_t)
{
  std::free(p);
}

You should never have to do this if you are compiling for an ordinary, hosted platform, so if you do need to do this, you better be familiar with the intricacies of memory management on your platform.

如果您正在编译一个普通的托管平台,那么您不应该这样做,所以如果您确实需要这样做,您最好熟悉平台上复杂的内存管理。

#2


15  

Sorry for posting in an old thread, but it's still pretty high in Google's search results and if you have this problem, you really should check out this link, because there it says that you simply need to link -lstdc++ and this is what solved the problem for me.

很抱歉在一个旧的线程中发布,但是它在谷歌的搜索结果中仍然很高,如果你有这个问题,你真的应该检查这个链接,因为它说你只需要链接-lstdc++ ++,这就是我解决问题的方法。

The following line was added by the Community without highlighting it as such and instead of just adding a comment to my answer for reasons that elude me: "Or use a C++ compiler that will implicitly add the -lstdc++ option, e.g. g++."

下面的代码是社区添加的,没有高亮显示它,而不是仅仅添加一个注释来解释我的原因:“或者使用一个c++编译器,它将隐式地添加-lstdc++选项,例如g++。”

#3


9  

I will just quote the documentation, since they put it better.

我只引用文档,因为他们写得更好。

Writing C++

编写c++

You can write programs for the AVR platform in C++, if you included c++ in the enabled-languages during configuration of avr-gcc. Just about everything in the Writing C AVR programs section applies, so read that first.

如果在AVR -gcc的配置过程中,在启用语言中包含c++,那么可以用c++为AVR平台编写程序。几乎所有的写作C AVR程序部分都适用,所以先读一下。

The major drawbacks of using C++ are:

使用c++的主要缺点是:

C++ calling convention side-effects
No libstdc++ support.

C++ calling convention side-effects

c++调用协定的副作用

Certain C++ features will automatically generate implied code if required, which can waste valuable program memory space and processor time. For instance, if at some point in the program a function is passed a C++ object by value:

如果需要,某些c++特性将自动生成隐含代码,这会浪费宝贵的程序内存空间和处理器时间。例如,在程序中的某个点,函数通过值传递一个c++对象:

void myfunction(MyCppClass object);

You will wind up with a default copy constructor being generated and called to create the temporary copy of object used in myfunction(). Be careful if this isn't what you want: equivalent behavior should be attainable by passing a reference to a constant MyCppClass object, while avoiding the code and execution overhead.

最后生成并调用一个默认的复制构造函数来创建myfunction()中使用的对象的临时副本。如果这不是您想要的,那么要小心:通过引用一个常量MyCppClass对象来实现等效行为,同时避免代码和执行开销。

Missing libstdc++ and other C++ features

缺少libstdc++ +和其他c++特性

None of the C++ standard templates, classes or functions are available. In addition, operators new and delete have yet to be implemented.

没有任何c++标准模板、类或函数可用。此外,新的和删除操作符还没有实现。

C++ exception support is also lacking. You'll probably need to make sure to use the -fno-exceptions compiler option to turn off the exceptions in the C++ front-end.

还缺少c++异常支持。您可能需要确保使用-fno-exception编译器选项来关闭c++前端中的异常。

What does work? Even though lots of the C++ goodies you are accustomed to working with aren't available, it can be worthwhile to program the AVR in C++. Constructors and destructors are functional and just the organizational advantages of using classes and object oriented programming may make C++ a great choice.

工作什么?尽管您习惯使用的许多c++特性都不可用,但在c++中编写AVR程序是值得的。构造函数和析构函数是函数性的,仅仅使用类和面向对象编程的组织优势就可能使c++成为一个很好的选择。

#4


4  

If you're just looking to do an interface, you don't need new/delete. Just remove the "virtual" from the base class destructor, and make sure the derived class has an implementation of __cxa_pure_virtual().

如果你只是想做一个界面,你不需要新的/删除。只需从基类析构函数中删除“virtual”,并确保派生类具有__cxa_pure_virtual()的实现。

Here is a compilable example. (I removed the returns to keep things simple, but it works just fine with them.)

下面是一个可编译的示例。(我删除了退货以保持简单,但这对他们来说是没问题的。)

In PacketWriter.h

在PacketWriter.h

class PacketWriter {
public:
    virtual void nextByte() = 0;
protected:
    ~PacketWriter() {}
};

In StringWriter.h

在StringWriter.h

#include "PacketWriter.h"

class StringWriter : public PacketWriter {
public:
    StringWriter(const char* message);
    void nextByte();
};  

In StringWriter.cpp

在StringWriter.cpp

#include "StringWriter.h"

// Definition of the error function to call if the constructor goes bonkers
extern "C" void __cxa_pure_virtual() { while (1); }

StringWriter::StringWriter(const char* message)
{
    // constructor code here
}

void StringWriter::nextByte()
{
}

Compile with avr-g++ StringWriter.cpp

与avr-g + + StringWriter.cpp编译