C++内存泄漏姿势之——eof()和delete释放内存
首先要说,用codeblocks的同学请抓紧卸载换到Visual Studio,好的IDE可以让你事半功倍!!
先说eof(),教训就是这玩意他并不会在读到最后一行之后就返回null值,他还会继续往后读,因为文件结束符是最后一个字符的下一个字符(是不是有点像字符串?),详见这篇博客:https://blog.csdn.net/rebel_321/article/details/4927464
贴代码:
1 void Graph::InputListGene(bool TOG,int nbNodes,ifstream& f){ 2 string* line = new string[nbNodes]; 3 int count =0; 4 while(!f.eof()){ 5 if(count >=nbNodes) break;//the eof character is the one after the last character 6 getline(f,line[count],';'); 7 cout<<line[count]<<endl; 8 count++; 9 }
如果没有第5行的if判断,第6行到最后一个循环会出现数组访问越界。
另外关于delete,这个东西吧,一定要记住它叫做“释放内存”,我个人理解为取消指针与其当前指向位置的关联。所以,并不是delete之后指针就空了,指针不会自己变成null,必须在delete后赋值null。
贴代码:
1 int id=p; 2 if(!TOG){//undirected 3 for (auto iter = listEdges.begin(); iter != listEdges.end(); iter++) {//to detect if the new edge is redundant 4 if ((*iter)->destination == e->source && (*iter)->source == e->destination) { //redundance detected 5 id = (*iter)->getID();//the id of an edge should be unique 6 //cout << "e id before del:" << e->id << endl; 7 p--; 8 delete e; 9 //cout << "e id :" << e->id << endl; 10 e = NULL; 11 break; 12 } 13 else 14 id = p; 15 } 16 } 17 if (e) {//if the new edge is not redundant 18 cout << "true,id is " <<e->id<< endl; 19 cout << "Edge_Id:" << e->id << " src:" << e->source->id << " dest:" << e->destination->id << " weight:" << e->cost << endl; 20 listEdges.push_back(e); 21 } 22 listVertex[i]->nextEdgeNode.push_back(make_pair(dest,id)); 23 p++; 24 delete[] cstr; 25 }
主要是第4行通过if判断排除掉不需要加入到listEdge里面的Edge对象,这里如果缺少第10行的话,第19行会报错,因为e一直是非空指针,17行并没有实现本来的判断null,相当于没有这个if。
找到一个说对这个问题解释得比较清楚的链接:https://www.zhihu.com/question/38998078
引用一下以下内容:“
可以发现nullptr最大的优势在于值是明确的,也就是说分辨一个指针是不是nullptr比分辨一个指针是不是野指针/悬垂指针要容易得多。那delete后置空指针的最大价值就在于明确资源当前状态。你想判断一个资源是否有效时,你当然没法直接跑去看这个资源在不在,而是得询问资源的持有者是否仍然持有这个资源。如果所有被delete的指针都被置为nullptr,以后再去访问这个指针的时候,我们可以通过其与nullptr的比较轻松判断出资源是否已经被delete。
作者:丁冬
链接:https://www.zhihu.com/question/38998078/answer/79321819
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
”