C ++内存泄漏形式将数据插入链表

时间:2016-04-17 20:18:33

标签: c++ pointers memory-leaks linked-list

我需要使用unique_ptr或shared_ptr作为我的链表,但我仍然遇到内存泄漏。就这种情况而言,我将所有成员数据保留为public。将第一次插入链接列表不会导致任何内存泄漏,但是当for循环继续时,每次我将对象作为数据插入链接列表时,调试器会显示更多内存泄漏。我不知道是什么导致这么多内存泄漏。它可能是由一些共享的ptrs引起的吗?

    template <typename T>
    class Node
    {
    public:
       T data;
       shared_ptr<Node<T>> next;
       shared_ptr<Node<T>> prev;

    public:
       Node() { next = NULL; prev = NULL; data = 0; }
       Node(T value) { next = NULL; prev = NULL; data = value; }
       T getData() { return data; }

    };

  template <typename T>
  class DoubleLinkedList
  {
  public:
      shared_ptr<Node<T>> head;
      shared_ptr<Node<T>> tail;
  public:
      DoubleLinkedList()
     {
         head = NULL;
         tail = NULL;
         total = 100;
         for (int i = 0; i < total; i++)
         {
            Insert(objectgetsinsertedhere);
         }
     }


void Insert(T data)
{
    shared_ptr<Node<T>> rover = NULL;
    T value(data);
    if (head == NULL)
    {
        head = make_shared<Node<T>>(data);
        tail = head;
    }
    else
    {
        shared_ptr<Node<T>> nu = make_shared<Node<T>>(data);
        nu->prev = tail;
        if (head == tail)
            head->next = nu;
        tail->next = nu;
        tail = nu;
    }
}
};

编辑:这是调试器显示内存泄漏的一部分。

Detected memory leaks!
Dumping objects ->
{211} normal block at 0x005CF798, 8 bytes long.
Data: <x \     > 78 98 5C 00 00 00 00 00 
{210} normal block at 0x005CF258, 8 bytes long.
Data: <\ \     > 5C 98 5C 00 00 00 00 00 
{209} normal block at 0x005CF1B0, 8 bytes long.
Data: <@ \     > 40 98 5C 00 00 00 00 00 
{205} normal block at 0x005C9830, 136 bytes long.
Data: <H               > 48 A9 0C 00 01 00 00 00 01 00 00 00 CD CD CD CD 
{191} normal block at 0x005CF3A8, 8 bytes long.
Data: <  \     > A8 DB 5C 00 00 00 00 00 
{190} normal block at 0x005CF0D0, 8 bytes long.
Data: <  \     > 8C DB 5C 00 00 00 00 00 
{189} normal block at 0x005CF060, 8 bytes long.
Data: <p \     > 70 DB 5C 00 00 00 00 00 
{185} normal block at 0x005CDB60, 136 bytes long.
Data: <H               > 48 A9 0C 00 01 00 00 00 01 00 00 00 CD CD CD CD 
Object dump complete.

1 个答案:

答案 0 :(得分:2)

问题是您的共享指针中有所有权周期。这使得内存不会自动释放,因为始终至少有一个所有者,即使在链表自身被销毁之后也是如此。解决此问题的一种方法是仅对下一个指针使用共享指针,而不是使用prev指针:

from django.db import models
from django.contrib.auth.models import AbstractUser #BASE
from django.contrib.auth.models import Group
from datetime import *

class User(AbstractUser):

    date = models.DateTimeField(auto_now_add = True)
    type = models.TextField(max_length=20)
    ########################################################
    def __str__(self):              # __unicode__ on Python 2
        return self.username


class CompteCandidat(User):
    name = models.TextField(max_length=50)
    prenom=models.TextField(max_length=50)
    sexe = models.TextField(max_length=10)
    datecr = models.DateTimeField(auto_now_add = True)
    cv = models.OneToOneField('CV',related_name="CompteCcv")
    demande=models.OneToOneField('Adresse',related_name="CompteCdemande")

    def __str__(self):              # __unicode__ on Python 2

        return self.name



class CompteRE(User):
    name = models.TextField(max_length=50)
    accronime = models.TextField(blank=False,null=False)
    fondateur = models.TextField(max_length=50)
    dateF= models.DateTimeField(auto_now = True,blank=False,null=False)
    site= models.TextField(max_length=20)
    fax=models.TextField(max_length=20)
    activite=models.TextField(max_length=20)

    def __str__(self):
        return self.name


class CompteRF(User):
    name = models.TextField(blank=False,null=False)
    accronime = models.TextField(blank=False,null=False)
    site= models.TextField(max_length=20)
    fax=models.TextField(max_length=20)
    #######################################################
    def __str__(self):
        return self.name

class CV(models.Model):
    numtel = models.IntegerField(blank=False,null=False)
    datecv= models.DateTimeField(auto_now = True,blank=False,null=False)
    pathcv = models.TextField(blank=False,null=False)
    compteCand = models.OneToOneField('CompteCandidat',related_name="cvss")
    competence=models.ManyToManyField('Competence',related_name="cvss",blank=True)
    #######################################################
    def __str__(self):
        return self.name


class Competence(models.Model):
    cv=models.ManyToManyField('CV',related_name="cv",blank=True)
    #######################################################
    def CVs(self):
        return self.cv.all()


class Diplome(Competence):
    type=models.TextField(blank=False,null=False)
    domaine=models.TextField(blank=False,null=False)
    specialite=models.TextField(blank=False,null=False)
    annee=models.DateTimeField(auto_now = False,blank=False,null=False)
    #######################################################


class CompetenceTech(Competence):
    domaine=models.TextField(blank=False,null=False)
    valeur=models.TextField(blank=False,null=False)
    #######################################################


class CompetenceLang(Competence):
    langue=models.TextField(blank=False,null=False)
    niveau=models.TextField(blank=False,null=False)
    #######################################################


class Adresse(models.Model):
    numV=models.IntegerField(blank=False,null=False)
    complementdest=models.TextField(blank=False,null=False)
    complementadr=models.TextField(blank=False,null=False)
    commune=models.TextField(blank=False,null=False)
    codeP=models.IntegerField(blank=False,null=False)
    pays=models.TextField(blank=False,null=False)
    compteCand=models.OneToOneField('CompteCandidat',related_name="ad")



class Demande(models.Model):
    nom=models.TextField(blank=False,null=False)
    prenom=models.TextField(blank=False,null=False)
    pathcv=models.TextField(blank=False,null=False)


class Stage(models.Model):
    typeposte=models.TextField(blank=False,null=False)
    diplome=models.TextField(blank=False,null=False)
    niveau=models.TextField(blank=False,null=False)
    duree=models.IntegerField(blank=False,null=False)
    commentaire=models.TextField(blank=False,null=False)

class FicheFormation(models.Model):
    intitule=models.TextField(blank=False,null=False)
    duree=models.IntegerField(blank=False,null=False)
    objective=models.TextField(blank=False,null=False)
    nbrUE=models.IntegerField(blank=False,null=False)
    niveau=models.TextField(blank=False,null=False)
    prix=models.IntegerField(blank=False,null=False)
    unitef=models.ManyToManyField('FicheFormation',related_name="fichef",blank=True)

class UniteFormation(models.Model):
    nomUe=models.TextField(blank=False,null=False)
    accronime=models.TextField(blank=False,null=False)
    commentaire=models.TextField(blank=True,null=True)

这可以防止所有权周期。列表拥有头部,头部拥有第二个元素,等等。当列表被销毁时,头部没有所有者,因此头部被破坏,现在第二个元素没有所有者,所以它得到了被毁坏等等。