2015-10-17 112 views
-1

我一直在努力处理内存泄漏,我正在编写一个程序来读取某些图像的颜色。内存泄漏问题C++程序

代码:http://ideone.com/dcU5Su

问题:我无法找出内存泄露/泄漏的根源。

我试过的是什么:我通过Valgrind运行程序。当中很多unprocessible信息,下面是错误,我可以让出:

  • Invalid write of size 4 [有这些3]
  • Conditional jump or move depends on uninitialised value(s)
  • Syscall param write(buf) points to uninitialised byte(s)

综观上述错误,我认为这个问题与不正确的初始化有关。但我无法看到在哪里。

+0

请解释原因之前,向下投票这个问题,我在这里是新的,所以请体谅,并帮助我改进 – Harry

+0

这是所有这些有缺陷的代码,它需要一个更大的文章来告诉什么。 –

+1

请在这里询问之前使用调试器,或抱怨反对票。 –

回答

1

你不应该这样做手动内存管理。使用向量:

#include <iostream> 
#include <sstream> 
#include <vector> 

struct Image { 
    unsigned int l; 
    unsigned int b; 
    unsigned int h; 
}; 

int main() 
{ 
    using namespace std; 

    std::vector<Image> image; 

    std::string line; 
    while(getline(cin,line)) 
    { 
     if(rand()%2) 
     { 
      istringstream iss(line); 

      Image img; 
      while (iss >> img.l >> img.b >> img.h) 
      { 
       image.push_back(img); 
      } 
     } 
    } 
} 

更新

既然你没有提供反馈(为什么delete[]似乎是你的样品中环内),我所能做的最好是张贴重构的建议包括修复/改进,我会做:

Live On Coliru

#include <iostream> 
#include <sstream> 

#include <cstring> 
#include <cassert> 

struct Image { 
    unsigned int l; 
    unsigned int b; 
    unsigned int h; 
}; 

class Images { 
    private: 
    size_t capacity; 
    size_t size; 

    Image *images; 

    Images& operator=(Images const&); // not supported 
    Images(Images const&);   // not supported 

    void autogrow() { 
     if (size >= capacity) { 
      int newCapacity = capacity * 2; 
      Image* newImage = new Image[newCapacity]; 
      std::cout << "growing " << capacity << " -> " << newCapacity << "\n"; 

      //only available in c++11: 
      static_assert(std::is_pod<Image>::value, "you're screwed"); 
      memcpy(newImage, images, size * sizeof(Image)); 

      capacity = newCapacity; 
      delete[] images; 
      images = newImage; 

     } 
    } 

    public: 
    Images() : capacity(1), size(0), images(new Image[capacity]) { 
     assert(images); 
    }; 
    ~Images() { 
     delete[] images; 
    } 

    Image& insert(Image const& img) { 
     autogrow(); 
     assert(size<capacity); 
     return images[size++] = img; 
    } 

}; 

int main() 
{ 
    using namespace std; 

    Images collection; 

    std::string line; 
    while(getline(cin,line)) 
    { 
     if(true) { 
      istringstream iss(line); 

      Image cur; 
      while (iss >> cur.l >> cur.b >> cur.h) { 
       collection.insert(cur); 
      } 
     } 
    } 
} 

打印,例如

od /dev/urandom -Anone -t u4 -w36 | head -1000 | ./a.out 
growing 1 -> 2 
growing 2 -> 4 
growing 4 -> 8 
growing 8 -> 16 
growing 16 -> 32 
growing 32 -> 64 
growing 64 -> 128 
growing 128 -> 256 
growing 256 -> 512 
growing 512 -> 1024 
growing 1024 -> 2048 
growing 2048 -> 4096 
+0

仍然看着你的代码给出一个更具体的提示什么是错的(https://www.livecoding.tv/sehe/,你的SSCCE坏了) – sehe

+0

我不想使用一个向量,你能否建议我最新的问题是什么实现 – Harry

+2

@Harry为什么你不想使用'std :: vector'? –

0

我想,当while (iss >> image[j].l >> image[j].b >> image[j].h)通过的第二次迭代路过的时候while循环中,image指针是无效的,因为你在上一次迭代中删除它被执行。

所以,delete[]第二次(内部while循环后),您应该重置变量荷兰国际集团image(就像你重新entring外while环路后的第一次。

// reset 
delete[] (image); 
capacity = 1; 
size = 0; 
j = 0; 
image = new Image[capacity]; 

或者,你应该把这个“重置”块放在外围的while的开头(并且在它之前摆脱初始化)

我不知道整个程序的逻辑,但是我想假设这是所需的行为...

编辑:所以这个问题可以通过移动size++;略高于if (size >= capacity)来解决(荣誉给@sehe寻找记忆违反:)的由来)

size++; 
if (size >= capacity) 
{ 
+0

我认为这个样本太破碎了,没有得出实际的结论,但我在我的回答中将它重构为一个工作混乱:) – sehe

+0

请看看这里:http://ideone.com/dcU5Su – Harry