First, let's look at a piece of code. The function is to implement IP address statistics. If an IP address appears three times, the corresponding processing is triggered, but each IP address statistics is always 1, as shown below,
Edgemonitor. h
# Include <unistd. h> # include <stdarg. h> # include <iostream> # include <string> # include <map> using namespace STD; # define edge_debug # ifdef edge_debug # define dbg_log (...) do {fprintf (stderr, "file: % s line % d-", _ file __, _ line _); \ fprintf (stderr, _ va_args _); \ fprintf (stderr, "\ n") ;}\ while (0) # else # define dbg_log (...) # endifstatic const int g_edge_connect_nr = 3; Enum {mail_warn_type_edge_smtp = 32}; c Lass cedgerecord {public: cedgerecord ();~ Cedgerecord (); int checknr (string & clientip); Private: int m_nr;}; Class cedgemonitor {public: cedgemonitor ();~ Cedgemonitor (); int addorupdaterecord (string & clientip, cedgerecord & r_outdata); int process (string & clientip); Private: Map <string, cedgerecord *> m_all_ipmap; // maintain the current and historical IP addresses of all IP addresses}; # endif
Edgemonitor. cpp
# Include "edgemonitor. H" cedgerecord: cedgerecord () {m_nr = 0;} cedgerecord ::~ Cedgerecord () {} int cedgerecord: checknr (string & clientip) {int warntype = 0; m_nr ++; If (m_nr> = g_edge_connect_nr) {warntype = mail_warn_type_edge_smtp; m_nr = 0;} dbg_log ("mail_edge_warn: clientip (% s), NR (% d), NR (% d)", clientip. c_str (), m_nr, g_edge_connect_nr); Return warntype;} cedgemonitor: cedgemonitor () {} cedgemonitor ::~ Cedgemonitor () {Map <string, cedgerecord * >:: iterator iter_rbtree_map; iter_rbtree_map = m_all_ipmap.begin (); While (iter_rbtree_map! = M_all_ipmap.end () {If (null! = Cursor-> second) {Delete iter_rbtree_map-> second; iter_rbtree_map-> second = NULL;} iter_rbtree_map ++;} m_all_ipmap.clear ();} int cedgemonitor :: addorupdaterecord (string & clientip, cedgerecord & r_outdata) {cedgerecord * p_record = NULL; If (m_all_ipmap.count (clientip) <1) {p_record = new cedgerecord (); if (null = p_record) {dbg_log ("failed to new cedgerecord"); Return-1;} m_all_ipmap. Insert (make_pair (clientip, p_record);} else {p_record = m_all_ipmap [clientip];} r_outdata = * p_record; return 0;} int cedgemonitor: Process (string & clientip) {cedgerecord r_outdata; int warntype = 0; // Add to history if (0! = Addorupdaterecord (clientip, r_outdata) {return-1;} // check the warning warntype = r_outdata.checknr (clientip); dbg_log ("warntype (% d)", warntype ); return 0;} int main () {string clientip ("172.22.1.16"); string clientip2 ("172.22.1.17"); string clientip3 ("172.22.1.18 "); cedgemonitor * Mm = new cedgemonitor (); Mm-> process (clientip ); mm-> process (clientip); Mm-> process (clientip2); Mm-> process (clientip2); Mm-> process (clientip2); Mm-> process (clientip2 ); delete mm; return 0 ;}
# G ++ edgemonitor. cpp
#./A. Out
File: edgemonitor. cpp line 23-mail_edge_warn: clientip (172.22.1.16), NR (1), NR (3)
File: edgemonitor. cpp line 88-warntype (0)
File: edgemonitor. cpp line 23-mail_edge_warn: clientip (172.22.1.16), NR (1), NR (3)
File: edgemonitor. cpp line 88-warntype (0)
File: edgemonitor. cpp line 23-mail_edge_warn: clientip (172.22.1.16), NR (1), NR (3)
File: edgemonitor. cpp line 88-Warntype (0)
File: edgemonitor. cpp line 23-mail_edge_warn: clientip (172.22.1.16), NR (1), NR (3)
File: edgemonitor. cpp line 88-warntype (0)
File: edgemonitor. cpp line 23-mail_edge_warn: clientip (172.22.1.17), NR (1), NR (3)
File: edgemonitor. cpp line 88-warntype (0)
File: edgemonitor. cpp line 23-mail_edge_warn: clientip (172.22.1.17), NR (1), NR (3)
File: edgemonitor. cpp line 88-warntype (0)
File: edgemonitor. cpp line 23-mail_edge_warn: clientip (172.22.1.17), NR (1), NR (3)
File: edgemonitor. cpp line 88-Warntype (0)
File: edgemonitor. cpp line 23-mail_edge_warn: clientip (172.22.1.17), NR (1), NR (3)
File: edgemonitor. cpp line 88-warntype (0)
The reason is that
R_outdata = * p_record;
The preceding statement indicates that the copy operator is called to copy the content of p_record to the space of r_outdata. In proccess, the operation to call the checknr () function is actually run in the copy space of p_record, therefore, the m_nr value is always 1.
Solution:
int CEdgeMonitor::addOrUpdateRecord(string &clientIP, CEdgeRecord **pp_outdata){。。。。。 *pp_outdata = p_record;}int CEdgeMonitor::process(string &clientIP){ CEdgeRecord *p_outdata = NULL; int ret = addOrUpdateRecord(clientIP, &p_outdata) if(0 != ret || NULL ==p_outdata ) { return -1; } warnType = p_outdata->checkNr(clientIP);。。。。}
# G ++ edgemonitor. cpp
#./A. Out
File: edgemonitor. cpp line 23-mail_edge_warn: clientip (172.22.1.16), NR (1), NR (3)
File: edgemonitor. cpp line 88-warntype (0)
File: edgemonitor. cpp line 23-mail_edge_warn: clientip (172.22.1.16), NR (2), NR (3)
File: edgemonitor. cpp line 88-warntype (0)
File: edgemonitor. cpp line 23-mail_edge_warn: clientip (172.22.1.16), NR (0), NR (3)
File: edgemonitor. cpp line 88-warntype (32)
File: edgemonitor. cpp line 23-mail_edge_warn: clientip (172.22.1.16), NR (1), NR (3)
File: edgemonitor. cpp line 88-warntype (0)
File: edgemonitor. cpp line 23-mail_edge_warn: clientip (172.22.1.17), NR (1), NR (3)
File: edgemonitor. cpp line 88-warntype (0)
File: edgemonitor. cpp line 23-mail_edge_warn: clientip (172.22.1.17), NR (2), NR (3)
File: edgemonitor. cpp line 88-warntype (0)
File: edgemonitor. cpp line 23-mail_edge_warn: clientip (172.22.1.17), NR (0), NR (3)
File: edgemonitor. cpp line 88-warntype (32)
File: edgemonitor. cpp line 23-mail_edge_warn: clientip (172.22.1.17), NR (1), NR (3)
File: edgemonitor. cpp line 88-warntype (0)