基本思想:内存释放学习和valgrind使用
#include <stdio.h>
#include <string.h>
class accept_pair {
public:
bool is_accept_state;
bool is_strict_end;
char *app_name;
public:
accept_pair(bool is_accept = false, bool is_end = false);
~accept_pair();
};
class DFA {
public:
unsigned int _size;
accept_pair **accept_states;
public:
DFA(int size);
~DFA();
void add_state(int index, char *s);
void add_size(int size);
};
int main() {
char *s = "Alexia";
DFA *dfa = new DFA(3);
dfa->add_state(0, s);
dfa->add_state(1, s);
dfa->add_state(2, s);
dfa->add_size(2);
dfa->add_state(3, s);
dfa->add_state(4, s);
printf("\napp_name: %s\n", dfa->accept_states[4]->app_name);
printf("size: %d\n\n", dfa->_size);
delete dfa;
return 0;
}
accept_pair::accept_pair(bool is_accept, bool is_end) {
is_accept_state = is_accept;
is_strict_end = is_end;
app_name = NULL;
}
accept_pair::~accept_pair() {
if (app_name) {
printf("delete accept_pair.\n");
delete[] app_name;
}
}
DFA::DFA(int size) {
_size = size;
accept_states = new accept_pair*[_size];
for (int s = 0; s < _size; s++) {
accept_states[s] = NULL;
}
}
DFA::~DFA() {
for (int i = 0; i < _size; i++) {
if (accept_states[i]) {
printf("delete dfa.\n");
delete accept_states[i];
accept_states[i] = NULL;
}
}
delete[] accept_states;
}
void DFA::add_state(int index, char *s) {
accept_states[index] = new accept_pair(true, true);
accept_states[index]->app_name = new char[strlen(s) + 1];
memcpy(accept_states[index]->app_name, s, strlen(s) + 1);
}
void DFA::add_size(int size) {
// reallocate memory for accept_states.
accept_pair **tmp_states = new accept_pair*[size + _size];
for (int s = 0; s < size + _size; s++){
tmp_states[s] =NULL;
}
//具体案例参考 https://blog.csdn.net/zxh2075/article/details/51983721?readlog
// 作者也做了详细解释,个人见解认为,如果按照博主的错误写法,会在dfa->add_state(3, s); dfa->add_state(4, s);再次被add_state函数内部重复申请空间
for (int s = 0; s < _size; s++) {
tmp_states[s] = new accept_pair(false, false);
tmp_states[s]->is_accept_state = accept_states[s]->is_accept_state;
tmp_states[s]->is_strict_end = accept_states[s]->is_strict_end;
if (accept_states[s]->app_name != NULL) {
tmp_states[s]->app_name = new char[strlen(accept_states[s]->app_name) + 1];
memcpy(tmp_states[s]->app_name, accept_states[s]->app_name, strlen(accept_states[s]->app_name) + 1);
}
}
// free old memory.
for (int s = 0; s < _size; s++) {
if (accept_states[s] != NULL) {
delete accept_states[s];
accept_states[s] = NULL;
}
}
_size += size;
delete []accept_states;
accept_states = tmp_states;
}
valgrind内存检查
ubuntu@ubuntu:~$ cat a.log
==11440== Memcheck, a memory error detector
==11440== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==11440== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==11440== Command: ./a.out
==11440== Parent PID: 3336
==11440==
==11440==
==11440== HEAP SUMMARY:
==11440== in use at exit: 72,704 bytes in 1 blocks
==11440== total heap usage: 21 allocs, 20 frees, 73,992 bytes allocated
==11440==
==11440== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1
==11440== at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11440== by 0x4EC3EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21)
==11440== by 0x40106F9: call_init.part.0 (dl-init.c:72)
==11440== by 0x401080A: call_init (dl-init.c:30)
==11440== by 0x401080A: _dl_init (dl-init.c:120)
==11440== by 0x4000C69: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so)
==11440==
==11440== LEAK SUMMARY:
==11440== definitely lost: 0 bytes in 0 blocks
==11440== indirectly lost: 0 bytes in 0 blocks
==11440== possibly lost: 0 bytes in 0 blocks
==11440== still reachable: 72,704 bytes in 1 blocks
==11440== suppressed: 0 bytes in 0 blocks
==11440==
==11440== For counts of detected and suppressed errors, rerun with: -v
==11440== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)