0

我正在尝试一个示例程序,我使用“malloc”分配内存并使用“free”取消分配内存......我知道使用“new”和“delete”是正确的方法,但我只是想要去理解……

我得到一个崩溃“分段违规”,但我不明白为什么......

class Object{
    public:
       Object(){
          this->def = 10;
          std::cout<<"Object Constructed"<<std::endl;
        }
        ~Object(){
             std::cout<<"Object Destructed"<<std::endl;
         }
         void amIPresent(){
              std::cout<<"Yes Object is Present, Defaulter is "<<this->def<<std::endl;
          }
     private:
         int def;
 };


 int main(){
     std::cout<<"Using malloc to Construct Object"<<std::endl;
     Object *o = static_cast<Object*>(malloc(sizeof(Object)));
     Object o2;
     o = &o2;
     std::cout<<"Freeing Memory using \"free\""<<std::endl;
      o->amIPresent();
      free(o);
      return 0;
 }

输出:

 Using malloc to Construct Object
 Object Constructed
 Freeing Memory using "free"
 Yes Object is Present, Defaulter is 10
 Segmentation fault
4

4 回答 4

4

因为您正在重新分配o指向一个不是用malloc. 所以调用free它是没有意义的。

于 2012-04-19T12:58:18.970 回答
2

当您释放 o 时,它指向分配在堆栈上的 o2 的地址(作为变量)。不得free用于堆栈对象。

于 2012-04-19T12:59:15.417 回答
0

我认为您误解了此代码的工作原理:

 Object *o = static_cast<Object*>(malloc(sizeof(Object)));
 Object o2;
 o = &o2;

第一的

 Object *o = static_cast<Object*>(malloc(sizeof(Object)));

将在堆上分配一块内存,变量 o 将指向它。

 Object o2;

将在堆栈上创建一个对象(在堆栈上分配,并调用构造函数)。

 o = &o2;

将使 o 指向堆栈上的该对象,它不再引用您使用 malloc 在堆上分配的内存。

所以当你使用

  free(o);

它会尝试释放堆栈上的内存,而不是你使用 malloc 分配的内存,所以你会崩溃。

你应该考虑安置新的。参见例如“安置新”有什么用途?

于 2012-04-19T13:08:30.557 回答
0

你已经声明了一个指针o,你在堆上分配了一些空间,但是你重新分配它指向一个基于堆栈的对象o2我不确定你这样做的逻辑是什么,这样做会导致内存泄漏。

然后,您释放与相关联的内存,o2但随后 'o2' 被破坏 - 因为所有基于堆栈的变量在您退出它们的范围时都会自动 - 它试图释放已释放的内存。

这里的问题是您正在混合基于堆栈和堆的对象。永远不要尝试删除(或释放)在堆栈上创建的对象,并且正如其他人所说,在 C++ 中坚持使用 new 和 delete 专门用于基于堆的对象。

于 2012-04-19T13:17:40.943 回答