这段c++代码存在内存泄露的可能么?我有10台电脑主板都自带1个com口

时间:2017-12-14 22:24:01   浏览:次   点击:次   作者:   来源:   立即下载

int main()n{n int* p = (int*)(new double);n delete p;n return ⓪;n}

这里假设int占④字节,double占⑧字节.

-----------------------------------------------------------

⑩分感谢各位大牛的耐心解答.

至少在我的思考以及Clang / LLVM 吐出的信息,我觉得不会泄漏。

在你的例子中,LLVM IR是这样的:

define i③② @main() #⓪ {entry: %retval = alloca i③② · align ④ %p = alloca i③②*, align ⑧ store i③② ⓪ · i③②* %retval, align ④ %call = call i⑧* @_Znwm(i⑥④ ⑧) #③ %⓪ = bitcast i⑧* %call to double* %① = bitcast double* %⓪ to i③②* store i③②* %① · i③②** %p, align ⑧ %② = load i③②*, i③②** %p, align ⑧ %isnull = icmp eq i③②* %② · null br i① %isnull, label %delete.end, label %delete.notnulldelete.notnull: ; preds = %entry %③ = bitcast i③②* %② to i⑧* call void @_ZdlPv(i⑧* %③) #④ br label %delete.enddelete.end: ; preds = %delete.notnull, %entry ret i③② ⓪}

new调用了_Znwm,delete是_ZdlPv,你可以通过c++filt来还原,也可以通过ast-dump来看

|-FunctionDecl ⓪x⑦f⑨③⑧⑨⓪⓪b④a⓪ line:①:⑤ main \'int (void)\'| `-CompoundStmt ⓪x⑦f⑨③⑧⑨⓪⓪be⓪⓪ | |-DeclStmt ⓪x⑦f⑨③⑧⑨⓪⓪bd④⑧ | | `-VarDecl ⓪x⑦f⑨③⑧⑨⓪⓪b⑥⓪⓪ col:①⓪ used p \'int *\' cinit| | `-CStyleCastExpr ⓪x⑦f⑨③⑧⑨⓪⓪bd②⓪ \'int *\' | | `-CXXNewExpr ⓪x⑦f⑨③⑧⑨⓪⓪bcb⑧ \'double *\' Function ⓪x⑦f⑨③⑧⑨⓪⓪b⑥d⑧ \'operator new\' \'void *(unsigned long)\'| |-CXXDeleteExpr ⓪x⑦f⑨③⑧⑨⓪⓪bda⓪ \'void\' Function ⓪x⑦f⑨③⑧⑨⓪⓪ba⓪⑧ \'operator delete\' \'void (void *) noexcept\'| | `-ImplicitCastExpr ⓪x⑦f⑨③⑧⑨⓪⓪bd⑧⑧ \'int *\' | | `-DeclRefExpr ⓪x⑦f⑨③⑧⑨⓪⓪bd⑥⓪ \'int *\' lvalue Var ⓪x⑦f⑨③⑧⑨⓪⓪b⑥⓪⓪ \'p\' \'int *\'| `-ReturnStmt ⓪x⑦f⑨③⑧⑨⓪⓪bde⑧ | `-IntegerLiteral ⓪x⑦f⑨③⑧⑨⓪⓪bdc⑧ \'int\' ⓪|-FunctionDecl ⓪x⑦f⑨③⑧⑨⓪⓪b⑥d⑧ implicit used operator new \'void *(unsigned long)\'| |-ParmVarDecl ⓪x⑦f⑨③⑧⑨⓪⓪b⑦c⑧ implicit \'unsigned long\'| `-VisibilityAttr ⓪x⑦f⑨③⑧⑨⓪⓪b⑦⑧⓪ Implicit Default|-FunctionDecl ⓪x⑦f⑨③⑧⑨⓪⓪b⑧③⓪ implicit operator new[] \'void *(unsigned long)\'| |-ParmVarDecl ⓪x⑦f⑨③⑧⑨⓪⓪b⑨②⓪ implicit \'unsigned long\'| `-VisibilityAttr ⓪x⑦f⑨③⑧⑨⓪⓪b⑧d⑧ Implicit Default|-FunctionDecl ⓪x⑦f⑨③⑧⑨⓪⓪ba⓪⑧ implicit used operator delete \'void (void *) noexcept\'| |-ParmVarDecl ⓪x⑦f⑨③⑧⑨⓪⓪baf⑧ implicit \'void *\'| `-VisibilityAttr ⓪x⑦f⑨③⑧⑨⓪⓪bab⓪ Implicit Default`-FunctionDecl ⓪x⑦f⑨③⑧⑨⓪⓪bb⑥⓪ implicit operator delete[] \'void (void *) noexcept\' |-ParmVarDecl ⓪x⑦f⑨③⑧⑨⓪⓪bc⑤⓪ implicit \'void *\' `-VisibilityAttr ⓪x⑦f⑨③⑧⑨⓪⓪bc⓪⑧ Implicit Default

总而言之,new调用的是\'operator new\' \'void *(unsigned long)\', delete是\'operator delete\' \'void (void *) noexcept\'

然后,我们看LLVM IR

%call = call i⑧* @_Znwm(i⑥④ ⑧) #③ %⓪ = bitcast i⑧* %call to double* %① = bitcast double* %⓪ to i③②* store i③②* %① · i③②** %p, align ⑧ %② = load i③②*, i③②** %p, align ⑧ %isnull = icmp eq i③②* %② · null br i① %isnull, label %delete.end, label %delete.notnulldelete.notnull: ; preds = %entry %③ = bitcast i③②* %② to i⑧* call void @_ZdlPv(i⑧* %③) #④

在这里,new记录的是分配大小为double的⑧ · 然后返回①个i⑧*出去,即分配的内存的地址。然后这个指针进行bitcast,无论说转换double*,然后再转换为i③②*,其实都记录下来了这个地址。然后这个i③②*指针,在传递给delete时,又转换为了i⑧*。所以经历了i⑧* -> double* ->i③②*->i⑧*。所以,你完全可以想象的到,delete的大小,跟类型指针完全没有任何关系。

然后我们打开operator new / delete的实现:

_LIBCPP_WEAKvoid *operator new(std::size_t size) _THROW_BAD_ALLOC{ if (size == ⓪) size = ①; void* p; while ((p = ::malloc(size)) == ⓪) { // If malloc fails and there is a new_handler, // call it to try free up memory. std::new_handler nh = std::get_new_handler(); if (nh) nh(); else#ifndef _LIBCPP_NO_EXCEPTIONS throw std::bad_alloc();#else break;#endif } return p;}_LIBCPP_WEAKvoidoperator delete(void* ptr) _NOEXCEPT{ if (ptr) ::free(ptr);}

也就是说其实依赖的是malloc / free 。这时候你可以想象①下C,无论是何种类型指针,如void *p = malloc(sizeof(int)); free(p);或者void *p = malloc(sizeof(double)); free(p);我们都是可以正常析构的,所以malloc / free 也肯定不是跟这个指针类型有关了。那么,若你对为什么free可以正常析构感兴趣,对我曾在这里简单提到过malloc之后再进行free,free的内存空间①定被OS回收了吗? - 知乎。你也可以参考这里:A quick tutorial on implementing and debugging malloc, free, calloc, and realloc,这里简单的探寻了malloc / free。

你都说了机器上只有①个串口。设备管理器里显示的第②个对你有意义吗?

收起

相关推荐

相关应用

平均评分 0人
  • 5星
  • 4星
  • 3星
  • 2星
  • 1星
用户评分:
发表评论

评论

  • 暂无评论信息