What kind of mistakes they make
1 : We could disable exception, today many major compilers could do that for us(g++, clang++, visual c++).
2 : If the constructor and destructor are trivial, new and delete don't need to call the constructor and destructor.
3 : The comparison is unfair, by default, new == malloc + constructor, delete = destructor + free.
For more details, you could check stack overflow.
In theory, compiler of c++ should be able to perform same performance about new and malloc, delete and free, but could the compiler do that?
Codes
c
#include <stdio.h> #include <stdlib.h> // pulls in declaration of malloc, free int main() { char *a = (char*)malloc(1024); for(int i = 0; i != 1024; ++i){ printf("%c", a[i]); } free(a); a = NULL; return 0; }
c++
#include <cstdio> int main() { char *a = new char[1024]; for(int i = 0; i != 1024; ++i){ printf("%c", a[i]); } delete []a; return 0; }
c assembly : clang -S -O3 -mllvm --x86-asm-syntax=intel mallocAndNew00.c
.section __TEXT,__text,regular,pure_instructions .globl _main .align 4, 0x90 _main: ## @main .cfi_startproc ## BB#0: ## %entry push RBP Ltmp3: .cfi_def_cfa_offset 16 Ltmp4: .cfi_offset rbp, -16 mov RBP, RSP Ltmp5: .cfi_def_cfa_register rbp push R14 push RBX Ltmp6: .cfi_offset rbx, -32 Ltmp7: .cfi_offset r14, -24 mov EDI, 1024 call _malloc mov R14, RAX mov EBX, 1 xor EDI, EDI jmp LBB0_1 .align 4, 0x90 LBB0_2: ## %for.body.for.body_crit_edge ## in Loop: Header=BB0_1 Depth=1 movsx EDI, BYTE PTR [R14 + RBX] inc RBX LBB0_1: ## %for.body ## =>This Inner Loop Header: Depth=1 call _putchar cmp EBX, 1024 jne LBB0_2 ## BB#3: ## %for.end mov RDI, R14 call _free xor EAX, EAX pop RBX pop R14 pop RBP ret .cfi_endproc .subsections_via_symbols
c++ assembly : clang++ -S -O3 -std=c++11 -mllvm --x86-asm-syntax=intel mallocAndNew00.cpp
.section __TEXT,__text,regular,pure_instructions .globl _main .align 4, 0x90 _main: ## @main .cfi_startproc ## BB#0: ## %entry push RBP Ltmp3: .cfi_def_cfa_offset 16 Ltmp4: .cfi_offset rbp, -16 mov RBP, RSP Ltmp5: .cfi_def_cfa_register rbp push R14 push RBX Ltmp6: .cfi_offset rbx, -32 Ltmp7: .cfi_offset r14, -24 mov EDI, 1024 call __Znam mov R14, RAX mov EBX, 1 xor EDI, EDI jmp LBB0_1 .align 4, 0x90 LBB0_2: ## %for.body.for.body_crit_edge ## in Loop: Header=BB0_1 Depth=1 movsx EDI, BYTE PTR [R14 + RBX] inc RBX LBB0_1: ## %for.body ## =>This Inner Loop Header: Depth=1 call _putchar cmp EBX, 1024 jne LBB0_2 ## BB#3: ## %for.end test R14, R14 je LBB0_5 ## BB#4: ## %delete.notnull mov RDI, R14 call __ZdaPv LBB0_5: ## %delete.end xor EAX, EAX pop RBX pop R14 pop RBP ret .cfi_endproc .subsections_via_symbols
This time the codes of c++ and c have some different, c++ call the assembly of new and delete(?), c call the assembly of malloc and new. c++ check the pointer is point to nullptr or not before delete, but c do not check it anyway.If you want the same behavior, call malloc and free in c++, do make sure what are you doing before you call malloc and free but not new and delete.
codes can download from github.
No comments:
Post a Comment