2014-01-17 37 views
1

我正在使用另一个C++编码器为我提供给我的示例代码。我是C++语言的新学生,我想知道是否有可能存在内存泄漏/中(PlacementHead.cpp)给我这个类文件中的错误:我的C++文件中是否有可能的内存泄漏?

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

PlacementHead::PlacementHead(int width, int height, int gap, char* s) { 
    width_ = width; 
    height_ = height; 
    gap_ = gap; 
    size_ = (width*height)+1; 
    set_ = new char[size_ + 1]; 
    from_ = new int[size_ + 1]; 
    original_ = new char[size_ + 1]; 
    strcpy(set_,s); 
    strcpy(original_,s); 
} 

PlacementHead::~PlacementHead() { 

} 

int PlacementHead::getSize() { return size_; } 
int PlacementHead::getHeight() { return height_; } 
int PlacementHead::getWidth() { return width_; } 
int PlacementHead::getGap() { return gap_; } 

// Palauttaa indeksissä i olevan suuttimen 
char PlacementHead::getNozzle(int i) { 
    return set_[i-1]; 
} 

// Asettaa indeksissä i olevan suuttimen 
void PlacementHead::setNozzle(int i, char c) { 
    set_[i-1] = c; 
} 

// Merkitsee suuttimen poimituksi poistamalla sen listasta 
void PlacementHead::markNozzle(int i, int bankPos) { 
    set_[i-1] = ' '; 
    from_[i-1] = bankPos; 
} 

// Palauttaa seuraavan poimimattoman suuttimen indeksin 
int PlacementHead::getNextUnmarkedPos() { 
    for (int i=0; i<size_; i++) { 
     if (set_[i]!=' ') { 
      return i+1; 
     } 
    } 
    return 0; 
} 

// Palauttaa suuttimen alkuperäisen sijainnin pankissa 
int PlacementHead::getBankPos(int i) { 
    return from_[i-1]; 
} 

// Plauttaa alkuperäisen ladontapaan suutinjärjestyksen 
void PlacementHead::reset() { 
    //for (int i=0; i<size_; i++) { 
    // set_[i] = original_[i]; 
    //} 
    strcpy(set_,original_); 
} 

// Tulostusmetodi 
void PlacementHead::print() { 
    std::cout << "ladontapaa:\n"; 
    for (int h=height_; h>0; h--) { 
     for (int w=width_; w>0; w--) { 
      int i = ((h-1)*width_)+w; 
      std::cout << getNozzle(i); 
     } 
     std::cout << "\n"; 
    } 
} 

PlacementHead.h:

#ifndef PLACEMENTHEAD_H 
#define PLACEMENTHEAD_H 

class PlacementHead { 
    public: 
     PlacementHead(int size, int rows, int gap, char* s); 
     ~PlacementHead(); 
     int getSize(); 
     int getHeight(); 
     int getWidth(); 
     int getGap(); 
     char getNozzle(int i); 
     void setNozzle(int i, char c); 
     void markNozzle(int i, int bankPos); 
     int getNextUnmarkedPos(); 
     int getBankPos(int i); 
     void reset(); 
     void print(); 
    private: 
     char* set_; 
     int* from_; 
     char* original_; 
     int size_; 
     int width_; 
     int height_; 
     int gap_; 
}; 

#endif 

我注意到有动态分配的内存,但我没有在任何地方看到delete ......这是一个问题吗?如果这是一个问题,我该如何解决这个问题?

Thnx任何帮助!

P.S.

我注意到,没有在此示例中使用关键字class?...你能像这样定义一个类?

+1

貌似3内存泄漏给我! –

+0

+1我也这么认为:D thnx的确认! – jjepsuomi

+2

在析构函数中需要3个'delete [] ...'。 –

回答

5

这是不可能没有看到类定义( 头)的说法;如果size_等都是类似 boost::shared_array,或std::unique_ptr,没有泄漏。 如果他们只是int*,就有泄漏。

当然,没有C++程序员会写这种代码 反正。该课程将包含std::vector<int>std::string。从我们在这里看到的来看,作者 不知道C++。

+0

+1 @JamesKanze感谢您的帮助,我包含了代码的头文件。这是你的意思吗? =) – jjepsuomi

+1

@jjepsuomi是的。正如我怀疑的那样,所讨论的变量是原始指针,所以它会泄漏。 marcin_j关于不遵守三的规则的观点基本上也是正确的,但是如果你使用'std :: vector'和'std :: string'(或者智能指针),你会自动获得深层复制语义(或者你可能会想要禁用复制和分配---如果该类表示某个外部实体,则通常不想支持它们)。 –

1

另一个问题是,你的代码不服从三(链接herehere

第一次,你会写这样的代码:

{ 
PlacementHead a(0,0,0,"asdsa"); 
PlacementHead b(0,0,0,"asdsa"); 
a = b; // line 1 
} // here segfault 

你会得到段错误,在line 1,指针会从b复制到a,一旦你最终有析构函数,指针将被删除两次,这是错误的。这被称为浅拷贝,你需要深拷贝,在那里分配新的数组。

1

代码已经泄漏。构造函数分配内存.Destructor或其他一些功能必须清理之前的对象被销毁