内存泄漏?怎么修?

时间:2018-02-16 11:53:12

标签: c++ memory-leaks linked-list valgrind abstract-data-type

我有自己的类使用LL实现队列和堆栈,源代码在我的机器上编译得很好但是在valgrind中抛出后它显示了一些内存泄漏

class S{
private:
struct Node{

int value;
Node* next; 

Node(int v, Node* n):value(v), next(n){}
};

Node* head;

S(const S& other) {}
S& operator=(const S& other) {}

public:
S():head(NULL){}


void push(unsigned int data){
    head = new Node(data, head);
}


class Q{
private:
struct Node{

int value;
Node* next;
Node(int v, Node* n):value(v), next(n){}
};

Node* head;
Node* tail;
int size;

Q(const Q& other) {}
Q& operator=(const Q& other) {}

public:
Q():head(NULL), tail(NULL), size(0){}

void push(int data){
    if (head == NULL) head = tail = new Node(data, tail);
    else{
        tail -> next = new Node(data, tail);
        tail = new Node(data, tail);
    }
    size++;
}

valgrind throw

我做错了什么?很多帮助将被赞赏:)欢呼

2 个答案:

答案 0 :(得分:2)

在你的类构造函数中:

    karB.lifePoint -= attackKickPoint;

这样:

PQ(int cap){
capacity = cap;
arr = new int [capacity++];
for (int i= 0; i < capacity; i++)       arr[i] = {0};}

首先返回容量,然后将其值增加1。 因此,当您在capacity++ 循环中填充数组时,您将超出数组范围,因为您的数组大小比容量值小for

答案 1 :(得分:2)

这不是“内存泄漏”。

这是内存损坏。您可以通过精心设计理解C ++中的数组是基于0而不是基于1来开始修复它。数组的第一个元素是array[0]而不是array[1],其他所有元素都基于此。以下是基于数组元素以数组元素#1开头的概念:

int top(){
    return arr[1];
}
void pop(){
    arr[1] = arr[size];

数组的第一个元素是元素#0,而不是元素#1,但这是基于数组中第一个元素是元素#1的概念构建的。

在分配数组大小之前添加1似乎是一种避免必须进行此调整的简单方法,但它只会导致更多的悲伤,混乱和错误。这就是为什么显然构造函数在分配数组之前会尝试增加数组的大小:

PQ(int cap){
    capacity = cap;
    arr = new int [capacity++];
    for (int i= 0; i < capacity; i++)       arr[i] = {0};
}

除了它不正确地增加它。这是一个后增量,因此,例如,如果cap为4,new int[4]会在capacity递增之前被分配。下一行尝试清除数组元素#0到#4,除了数组元素#4不存在,代码尝试初始化它,运行数组的末尾,valgrind抛出一个红色标记

虽然只需使用预增量而不是后增量就可以解决这个问题,但正确的解决方案根本不是递增,而是重构代码,使其遵循C ++数组的自然属性为0,而不是基于1的。