指针和整数模板的内存泄漏。我究竟做错了什么?
Memory leak with template for pointers and ints. What am i doing wrong?
了解 C++,并尝试将 class 模板化以使用结构的 Int 和指针。
输出符合预期,但用 valgrind 测试似乎有内存韭菜,来自未释放的内存。
我相信这与我在 class 初始化中声明列表变量的方式有关。
我错过了什么,我该如何解决?
谢谢
#include <stdio.h>
template <class T>
class List {
T* list;
public:
int length;
List(int len) {
list = new T[len];
length = len;
}
virtual ~List() {
delete[] list;
}
T get(int index) {
return list[index];
}
void set(int index, T val) {
list[index] = val;
}
};
/*
You shouldn't change the code below, unless you want to _temporarily_ change the main function while testing.
Change it back when you're done.
*/
typedef struct Point_ {
int x;
int y;
} Point;
int main(){
List<int> integers(10);
for(int i = 0; i < integers.length; i++){
integers.set(i, i * 100);
printf("%d ", integers.get(i));
}
printf("\n"); // this loop should print: 0 100 200 300 400 500 600 700 800 900
List<Point *> points(5);
for(int i = 0; i < points.length; i++) {
Point *p = new Point;
p->x = i * 10;
p->y = i * 100;
points.set(i, p);
printf("(%d, %d) ", points.get(i)->x, points.get(i)->y);
delete p;
}
printf("\n"); // this loop should print: (0, 0) (10, 100) (20, 200) (30, 300) (40, 400)
}
像这样用 g++ 编译:
g++ -Wall p2_templates.cpp -o p2_templates
通过此命令使用 valgrind:
valgrind --tool=memcheck ./p2_templates
从 valgrind 获取此结果:
==22396== Memcheck, a memory error detector
==22396== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==22396== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==22396== Command: ./p2_templates
==22396==
0 100 200 300 400 500 600 700 800 900
(0, 0) (10, 100) (20, 200) (30, 300) (40, 400)
==22396==
==22396== HEAP SUMMARY:
==22396== in use at exit: 72,704 bytes in 1 blocks
==22396== total heap usage: 9 allocs, 8 frees, 73,848 bytes allocated
==22396==
==22396== LEAK SUMMARY:
==22396== definitely lost: 0 bytes in 0 blocks
==22396== indirectly lost: 0 bytes in 0 blocks
==22396== possibly lost: 0 bytes in 0 blocks
==22396== still reachable: 72,704 bytes in 1 blocks
==22396== suppressed: 0 bytes in 0 blocks
==22396== Rerun with --leak-check=full to see details of leaked memory
==22396==
==22396== For counts of detected and suppressed errors, rerun with: -v
==22396== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
首先非常仔细和完整地阅读 valgrind 输出(并按照 valgrind 的建议进行所有操作)。在您的情况下,感兴趣的片段是:
Rerun with --leak-check=full to see details of leaked memory
still reachable: 72,704 bytes in 1 blocks
您还应该注意以下事项:
http://valgrind.org/docs/manual/faq.html#faq.reports(4.1。我的程序使用 C++ STL 和字符串 类。Valgrind 报告“still reachable”内存泄漏涉及这些 类 在出口处的程序,但应该有 none).
如果您有时间,您可能会从详细了解这一点中受益匪浅:http://valgrind.org/docs/manual/mc-manual.html#mc-manual.leaks(4.2.8. 内存泄漏检测)。
您终于可以在这里找到大量有用的信息:http://valgrind.org(valgrind 主页)。
掌握基本的数据结构就好了!我鼓励您充分探索它。一旦掌握了基础知识,STL 就可以非常有用地帮助您在思考难题的同时处理繁忙的工作。
您的代码没有泄漏。 Valgrind 在其他地方查看内存,如前所述,您可以使用 --leak-check=full 来获取更多详细信息。很好,您正在尝试了解这些细节。
然而,这是一个悬空指针问题。
#include <stdio.h>
template <class T>
class List {
T* list;
public:
int length;
List(int len) {
list = new T[len];
length = len;
}
virtual ~List() {
delete[] list;
}
T get(int index) {
return list[index];
}
void set(int index, T val) {
list[index] = val;
}
};
/*
You shouldn't change the code below, unless you want to _temporarily_ change the main function while testing.
Change it back when you're done.
*/
typedef struct Point_ {
int x;
int y;
} Point;
int main(){
List<int> integers(10);
for(int i = 0; i < integers.length; i++){
integers.set(i, i * 100);
printf("%d ", integers.get(i));
}
printf("\n"); // this loop should print: 0 100 200 300 400 500 600 700 800 900
List<Point *> points(5);
for(int i = 0; i < points.length; i++) {
Point *p = new Point;
p->x = i * 10;
p->y = i * 100;
points.set(i, p);
printf("(%d, %d) ", points.get(i)->x, points.get(i)->y);
delete p;
}
Point* fail = points.get(0);
fail->x = 0;
fail->y = 0;
printf("\n"); // this loop should print: (0, 0) (10, 100) (20, 200) (30, 300) (40, 400)
}
请注意,我在点循环之后添加了 'fail' 变量来演示该问题。 points 变量已声明并填充正常,但随后内容被删除。 List 包含 Point* 而不是 Point,因此当删除发生时,List 中的指针是 'dangling'。几乎每次使用悬挂指针都会导致堆崩溃或损坏。这是 STL 容器以及保存指针时的常见问题。
C++ 的一大缺陷是堆管理。正确使用堆非常困难,最大的问题是所有权移交。悬挂指针或泄漏通常是由于对谁拥有指针的混淆而导致的。这里有一篇简短的文章Avoiding Leaks in C++
运行这个程序在Valgrind下会显示Invalid write错误。试一试。
了解 C++,并尝试将 class 模板化以使用结构的 Int 和指针。 输出符合预期,但用 valgrind 测试似乎有内存韭菜,来自未释放的内存。
我相信这与我在 class 初始化中声明列表变量的方式有关。
我错过了什么,我该如何解决? 谢谢
#include <stdio.h>
template <class T>
class List {
T* list;
public:
int length;
List(int len) {
list = new T[len];
length = len;
}
virtual ~List() {
delete[] list;
}
T get(int index) {
return list[index];
}
void set(int index, T val) {
list[index] = val;
}
};
/*
You shouldn't change the code below, unless you want to _temporarily_ change the main function while testing.
Change it back when you're done.
*/
typedef struct Point_ {
int x;
int y;
} Point;
int main(){
List<int> integers(10);
for(int i = 0; i < integers.length; i++){
integers.set(i, i * 100);
printf("%d ", integers.get(i));
}
printf("\n"); // this loop should print: 0 100 200 300 400 500 600 700 800 900
List<Point *> points(5);
for(int i = 0; i < points.length; i++) {
Point *p = new Point;
p->x = i * 10;
p->y = i * 100;
points.set(i, p);
printf("(%d, %d) ", points.get(i)->x, points.get(i)->y);
delete p;
}
printf("\n"); // this loop should print: (0, 0) (10, 100) (20, 200) (30, 300) (40, 400)
}
像这样用 g++ 编译:
g++ -Wall p2_templates.cpp -o p2_templates
通过此命令使用 valgrind:
valgrind --tool=memcheck ./p2_templates
从 valgrind 获取此结果:
==22396== Memcheck, a memory error detector
==22396== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==22396== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==22396== Command: ./p2_templates
==22396==
0 100 200 300 400 500 600 700 800 900
(0, 0) (10, 100) (20, 200) (30, 300) (40, 400)
==22396==
==22396== HEAP SUMMARY:
==22396== in use at exit: 72,704 bytes in 1 blocks
==22396== total heap usage: 9 allocs, 8 frees, 73,848 bytes allocated
==22396==
==22396== LEAK SUMMARY:
==22396== definitely lost: 0 bytes in 0 blocks
==22396== indirectly lost: 0 bytes in 0 blocks
==22396== possibly lost: 0 bytes in 0 blocks
==22396== still reachable: 72,704 bytes in 1 blocks
==22396== suppressed: 0 bytes in 0 blocks
==22396== Rerun with --leak-check=full to see details of leaked memory
==22396==
==22396== For counts of detected and suppressed errors, rerun with: -v
==22396== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
首先非常仔细和完整地阅读 valgrind 输出(并按照 valgrind 的建议进行所有操作)。在您的情况下,感兴趣的片段是:
Rerun with --leak-check=full to see details of leaked memory
still reachable: 72,704 bytes in 1 blocks
您还应该注意以下事项: http://valgrind.org/docs/manual/faq.html#faq.reports(4.1。我的程序使用 C++ STL 和字符串 类。Valgrind 报告“still reachable”内存泄漏涉及这些 类 在出口处的程序,但应该有 none).
如果您有时间,您可能会从详细了解这一点中受益匪浅:http://valgrind.org/docs/manual/mc-manual.html#mc-manual.leaks(4.2.8. 内存泄漏检测)。
您终于可以在这里找到大量有用的信息:http://valgrind.org(valgrind 主页)。
掌握基本的数据结构就好了!我鼓励您充分探索它。一旦掌握了基础知识,STL 就可以非常有用地帮助您在思考难题的同时处理繁忙的工作。
您的代码没有泄漏。 Valgrind 在其他地方查看内存,如前所述,您可以使用 --leak-check=full 来获取更多详细信息。很好,您正在尝试了解这些细节。
然而,这是一个悬空指针问题。
#include <stdio.h>
template <class T>
class List {
T* list;
public:
int length;
List(int len) {
list = new T[len];
length = len;
}
virtual ~List() {
delete[] list;
}
T get(int index) {
return list[index];
}
void set(int index, T val) {
list[index] = val;
}
};
/*
You shouldn't change the code below, unless you want to _temporarily_ change the main function while testing.
Change it back when you're done.
*/
typedef struct Point_ {
int x;
int y;
} Point;
int main(){
List<int> integers(10);
for(int i = 0; i < integers.length; i++){
integers.set(i, i * 100);
printf("%d ", integers.get(i));
}
printf("\n"); // this loop should print: 0 100 200 300 400 500 600 700 800 900
List<Point *> points(5);
for(int i = 0; i < points.length; i++) {
Point *p = new Point;
p->x = i * 10;
p->y = i * 100;
points.set(i, p);
printf("(%d, %d) ", points.get(i)->x, points.get(i)->y);
delete p;
}
Point* fail = points.get(0);
fail->x = 0;
fail->y = 0;
printf("\n"); // this loop should print: (0, 0) (10, 100) (20, 200) (30, 300) (40, 400)
}
请注意,我在点循环之后添加了 'fail' 变量来演示该问题。 points 变量已声明并填充正常,但随后内容被删除。 List 包含 Point* 而不是 Point,因此当删除发生时,List 中的指针是 'dangling'。几乎每次使用悬挂指针都会导致堆崩溃或损坏。这是 STL 容器以及保存指针时的常见问题。
C++ 的一大缺陷是堆管理。正确使用堆非常困难,最大的问题是所有权移交。悬挂指针或泄漏通常是由于对谁拥有指针的混淆而导致的。这里有一篇简短的文章Avoiding Leaks in C++
运行这个程序在Valgrind下会显示Invalid write错误。试一试。