Утечка памяти в C ++ при попытке удалить первый элемент связного списка указателей - PullRequest
0 голосов
/ 04 января 2012

Я довольно новичок в C ++, и у меня большие проблемы уже два дня.Я пытаюсь сделать многопоточный рендеринг (raycasting, multisampling, ambientocclusion) с потоками posix и каждый раз, когда я запускаю программу, она потребляет около 5 ГБ ОЗУ (после запуска потоков) до завершения.Итак, очевидно, у меня есть утечка памяти.Мои рабочие потоки работают так:

struct Job
{
    AOSampler sampler;
    Ray ray;
    bool abool;
    int someint;
    .
    .
    //no pointers here
};
//global
//use of C++ STL list
list<Job*> * jobs;


//Part of thread posix function starts here
list<Job*> tjobs;
// Mark 1    

//Pushing and popping between "tjobs" the threadjobs just for this thread and the global jobpool "jobs". Of course threadsafe with mutex locking.
//The thread pops jobs from "jobs" and puts em into "tjobs"

while(!tjobs.empty())
{
    //many calculations but all vars are on stack, besides creating new jobs an pushing them to some other queue, which will be pushed into "jobs" later

    // !!!THE PROBLEM!!!
    delete (tjobs.front());
    tjobs.pop_front();
    // The memory in htop always rises but never decreases!
}
// jumps to Mark 1
// end of multithread while

Код компилируется, выполняется и завершается на многих ядрах, но производительность плохая (4 нормально, 24 плохо, это 24-ядерный компьютер).Я думаю, что это может быть из-за использования памяти 5 ГБ (четверть всего физ. Оперативной памяти), но операционная система и кэш могут не справиться с этим хорошо.

Я отчаянно пытаюсь найти решение для моейпроблема.Мой поиск в Google не помог мне вообще.Я надеюсь, что вы можете сделать.любая помощь высоко ценится.

Спасибо

(извините за мой английский)

Edit1: забыл упомянуть, что у него еще нет вывода -> Я не могупроверьте, действительно ли это

Edit2: Некоторые заголовки:

class AOSampler
{
public:
    AOSampler();
    /// constructor that initializes the sampler, just calls init
    AOSampler(vec3 const & normal, vec3 const & color);
    /// initializes the sampler
    void init(vec3 const & normal, vec3 const & color);
    /// returns an importance sampled random direction and the associated weight
    void sample(vec3 & sampledDirection, vec3 & sampleWeight) const;
private:
    /// orthonormal basis
    vec3 m_normal;
    vec3 m_tangent;
    vec3 m_bitangent;
    /// diffuse color
    vec3 m_color;
};

class Ray
{
public:
    Ray() : tMin(0.001f), tMax(FLT_MAX){}
    vec3 origin;
    vec3 direction;
    float tMin, tMax;
};

class vec3
{
public:
    float x,y,z;

    vec3();
    vec3(float a, float b, float c);

    /// assignment operator that assigns a single scalar value to all components
    void operator=(float v);

    /// unsafe element access 
    float operator[](unsigned int i) const
    {
        return (&x)[i];
    }

    /// length of the vector
    float length() const;

    ///Returns a normalized version of the vector
    vec3 normalize() const;

    /// componentwise summation
    vec3 add(const vec3& a) const;

    /// componentwise subtraction
    vec3 subtract(const vec3& a) const;

    ///compute the dot product which is cos(alpha) * this.Length * a.Length
    ///where alpha is the (smaller) angle between the vectors
    float dot(const vec3& a) const;

    float minComponent() const;
    float maxComponent() const;

    ///computes a vector which is orthogonal to both of the input vectors
    static vec3 cross(const vec3& a, const vec3& b);
    static vec3 min(const vec3& a, const vec3& b);
    static vec3 max(const vec3& a, const vec3& b);

    /// add a vector to this vector
    void operator+=( vec3 const & v );
    /// subtract a vector from this vector
    void operator-=( vec3 const & v );
};

Ответы [ 2 ]

1 голос
/ 04 января 2012

Ваш цикл while зацикливается только тогда, когда список пуст, а затем вы пытаетесь удалить несуществующий первый элемент. Конечно, это вызовет странное поведение. Или, скорее, вы уже положили элементы в очередь и никогда не вытаскиваете их, что может привести к их постоянному росту.

Итак, давайте предположим, что вы не показываете свой реальный код, но что-то набрали повторно и забыли символ !, и цикл while правильный.

В таком случае вы уверены, что это на самом деле утечка? Возможно, ваш процесс использует больше памяти, но если он ее освобождает (что, по-видимому, условно), процесс сможет использовать ее повторно, даже если ОС не видит память в htop. Вы можете использовать valgrind, чтобы получить более полное представление о том, действительно ли вы протекаете или нет.

0 голосов
/ 04 января 2012

Трудно обнаружить утечки памяти, даже если у вас есть доступ к исходному коду. Попробуйте использовать инструмент для обнаружения утечек, такой как Valgrind: http://www.cprogramming.com/debugging/valgrind.html Это хорошая инвестиция.

...