C++ 对“operator delete(void*)”的未定义引用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7015285/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:21:41  来源:igfitidea点击:

Undefined reference to 'operator delete(void*)'

c++embeddeddestructoravravr-gcc

提问by Bracket

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

谢谢

采纳答案by Kerrek SB

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 newand delete. In the simplest case, you could simply wrap malloc, or allocate memory from your own favourite source:

如果您出于某种原因没有链接标准库(嵌入式场景中很可能就是这种情况),您必须提供自己的运算符newdelete. 在最简单的情况下,您可以简单地 wrap 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.

如果您正在为普通的托管平台进行编译,则永远不必这样做,因此,如果您确实需要这样做,则最好熟悉平台上内存管理的复杂性。

回答by Alex

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.

很抱歉在旧线程中发帖,但它在 Google 的搜索结果中仍然很高,如果您遇到此问题,您真的应该查看此链接,因为它说您只需要链接 -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++."

社区添加了以下行,但没有将其突出显示,而是出于我无法理解的原因仅在我的答案中添加评论:“或者使用将隐式添加 -lstdc++ 选项的 C++ 编译器,例如 g++。”

回答by Vinicius Kamakura

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

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

Writing 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.

The major drawbacks of using C++ are:

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

C++ calling convention side-effects

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:

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.

Missing libstdc++ and other C++ features

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

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.

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++

如果在配置 avr-gcc 期间将 c++ 包含在启用的语言中,则可以使用 C++ 为 AVR 平台编写程序。编写 C AVR 程序部分中的几乎所有内容都适用,因此请先阅读。

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

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

C++ 调用约定的副作用

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

void myfunction(MyCppClass object);

您将最终生成一个默认的复制构造函数,并调用它来创建 myfunction() 中使用的对象的临时副本。如果这不是您想要的,请小心:通过传递对常量 MyCppClass 对象的引用应该可以获得等效的行为,同时避免代码和执行开销。

缺少 libstdc++ 和其他 C++ 功能

没有任何 C++ 标准模板、类或函数可用。此外,操作符 new 和 delete 尚未实现。

也缺乏 C++ 异常支持。您可能需要确保使用 -fno-exceptions 编译器选项来关闭 C++ 前端中的异常。

有什么作用?尽管您习惯使用的许多 C++ 好东西不可用,但使用 C++ 对 AVR 进行编程是值得的。构造函数和析构函数是函数式的,使用类和面向对象编程的组织优势可能使 C++ 成为一个很好的选择。

回答by MikeTwo

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().

如果您只是想做一个界面,则不需要新建/删除。只需从基类析构函数中删除“虚拟”,并确保派生类具有 __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