C++ 中的内存泄漏 (Valgrind)
Memory leak in C++ (Valgrind)
我用最少的实现堆栈。在这个程序中,我从 valgrind 得到一个错误。 push() 和 main() 函数有问题。当我添加删除 st;到 push() 函数,我得到更多的错误。我通过 valgrind ./a.out 检查它。抱歉,代码很长。我还为堆栈编写了其余的函数。但是他们没有错误,我把那些可能有错误的代码留在了代码中。
#include <cstring>
#include <iostream>
struct Stack {
int data;
int min;
Stack* next;
};
void Push(Stack** top, int n) {
Stack* st = new Stack();
st->data = n;
if (*top == NULL) {
*top = st;
(**top).min = n;
} else {
st->min = ((n <= (**top).min) ? n : (**top).min);
st->next = *top;
*top = st;
}
std::cout << "ok" << std::endl;
}
void Pop(Stack** top) {
if (*top != NULL) {
std::cout << (**top).data << std::endl;
*top = (*top)->next;
} else {
std::cout << "error" << std::endl;
}
}
int main() {
Stack* top = nullptr;
int m;
std::cin >> m;
std::string str;
for (int i = 0; i < m; ++i) {
std::cin >> str;
if (str == "push") {
int value;
std::cin >> value;
Push(&top, value);
}
if (str == "pop") {
Pop(&top);
}
}
delete top;
}
当你只是 delete top
时,你会销毁它(在你的情况下它没什么,但如果有兴趣,你可以分散自己的注意力阅读有关 destructors 的内容)并释放分配给 [=13 的动态内存=].但是,您实际上还想 delete
top->next
、top->next->next
(如果存在)等。修补程序:
while (top) { // same as "while (top != nullptr) {"
Stack* next = top->next; // we can't use `top` after we `delete` it, save `next` beforehand
delete top;
top = next;
}
现在,关于更一般的事情。该课程教你一些非常古老的 C++(几乎只是普通的 C;尽管这里的 C 也很糟糕)。至少,您的整个 Push()
可以替换为(感谢 lvalue references (Type&
), std::min
and aggregate initialization):
void push(Stack*& top, int n) {
top = new Stack{n, std::min(n, top ? top->min : n), top};
std::cout << "ok\n";
}
I'm new to C++ programming. I used to write in Python
干得好。可悲的是,这样的教学表明 C++ 太古老和可怕了。
编辑
here's a new in Push, so there should most likely be a delete in Pop
没错(感谢@molbdnilo)。你应该 delete
pop
ped 元素而不是仅仅泄漏它们。
我用最少的实现堆栈。在这个程序中,我从 valgrind 得到一个错误。 push() 和 main() 函数有问题。当我添加删除 st;到 push() 函数,我得到更多的错误。我通过 valgrind ./a.out 检查它。抱歉,代码很长。我还为堆栈编写了其余的函数。但是他们没有错误,我把那些可能有错误的代码留在了代码中。
#include <cstring>
#include <iostream>
struct Stack {
int data;
int min;
Stack* next;
};
void Push(Stack** top, int n) {
Stack* st = new Stack();
st->data = n;
if (*top == NULL) {
*top = st;
(**top).min = n;
} else {
st->min = ((n <= (**top).min) ? n : (**top).min);
st->next = *top;
*top = st;
}
std::cout << "ok" << std::endl;
}
void Pop(Stack** top) {
if (*top != NULL) {
std::cout << (**top).data << std::endl;
*top = (*top)->next;
} else {
std::cout << "error" << std::endl;
}
}
int main() {
Stack* top = nullptr;
int m;
std::cin >> m;
std::string str;
for (int i = 0; i < m; ++i) {
std::cin >> str;
if (str == "push") {
int value;
std::cin >> value;
Push(&top, value);
}
if (str == "pop") {
Pop(&top);
}
}
delete top;
}
当你只是 delete top
时,你会销毁它(在你的情况下它没什么,但如果有兴趣,你可以分散自己的注意力阅读有关 destructors 的内容)并释放分配给 [=13 的动态内存=].但是,您实际上还想 delete
top->next
、top->next->next
(如果存在)等。修补程序:
while (top) { // same as "while (top != nullptr) {"
Stack* next = top->next; // we can't use `top` after we `delete` it, save `next` beforehand
delete top;
top = next;
}
现在,关于更一般的事情。该课程教你一些非常古老的 C++(几乎只是普通的 C;尽管这里的 C 也很糟糕)。至少,您的整个 Push()
可以替换为(感谢 lvalue references (Type&
), std::min
and aggregate initialization):
void push(Stack*& top, int n) {
top = new Stack{n, std::min(n, top ? top->min : n), top};
std::cout << "ok\n";
}
I'm new to C++ programming. I used to write in Python
干得好。可悲的是,这样的教学表明 C++ 太古老和可怕了。
编辑
here's a new in Push, so there should most likely be a delete in Pop
没错(感谢@molbdnilo)。你应该 delete
pop
ped 元素而不是仅仅泄漏它们。