// File: MingYueRuYa[P]cprimeprimecode/memory_manager.cpp
// Function: demo03::test_array_new_and_placement_new()
void test_array_new_and_placement_new()
{
	cout << "\ntest_placement_new()............... \n";
	size_t size = 3;
{
//case 1
//模拟memory pool的做法，array new + placement new，崩溃
	A *buf  = (A *)(new char[sizeof(A)*size]);
	A *temp = buf;
	cout << "buf=" << buf << " temp=" << temp << endl;

	for (int i=0; i<size; ++i) {
		new(temp++) A(i);	//3次 copy ctor
	}
	//! delete [] buf; //crash . why?
					   //因为这其实个char array, 看到 delete [] buf; 编译器会企图唤起多次A::~A()
					   //但array memory layout中找到与array元素（本例3）相关的信息
					   //--整个格局都是错乱（从我对VC的认识而言），于是崩溃
					   //error message:*** Error in `./memory_manager': free(): invalid next size (fast): 0x01735040 ***
	delete buf;		   //dtor just one time3, ~[0]
}
{
//case 2
//测试单纯的array new
	A *buf = new A[size]; //default ctor 3 times, [0]->[1]->[2]
						  //A必须有default ctor，否则[Error] no matching function for call to 'demo02::A::A()'
	A *temp = buf;
	cout << "buf=" << buf << " temp=" << temp << endl;

	for (int i=0; i<size; ++i) {
		new(temp++) A(i);	//3次 ctor
	}
	cout << "buf=" << buf << " temp=" << temp << endl;
	delete [] buf;		 //dtor three times (次序逆反，[2]->[1]->[0])
}
{
//case 3
//掌握崩溃的原因，再次模拟memory pool做法，array new + placement new.
//不用做了，因为memory pool只是提供memory，它并不管construction，
//也不管destruction，它只负责回收memory.
//所以它是以void *或char *取得memory，释放的也是void * or char *.
//不像本例case 1 释放的是A*
//
//事实上 memory pool 形式如demo04::test
}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq 0x66e6(%rip), %rdi      # 0x8fd8
leaq 0x3783(%rip), %rsi      # 0x607c
callq 0x2190
movq $0x3, -0x8(%rbp)
movq -0x8(%rbp), %rdi
shlq $0x2, %rdi
callq 0x2030
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x18(%rbp)
movq 0x66b2(%rip), %rdi      # 0x8fd8
leaq 0x3776(%rip), %rsi      # 0x60a3
callq 0x2190
movq %rax, %rdi
movq -0x10(%rbp), %rsi
callq 0x2130
movq %rax, %rdi
leaq 0x3760(%rip), %rsi      # 0x60a8
callq 0x2190
movq %rax, %rdi
movq -0x18(%rbp), %rsi
callq 0x2130
movq %rax, %rdi
movq 0x6655(%rip), %rsi      # 0x8fb8
callq 0x21c0
movl $0x0, -0x1c(%rbp)
movslq -0x1c(%rbp), %rax
cmpq -0x8(%rbp), %rax
jae 0x299b
movq -0x18(%rbp), %rdi
movq %rdi, %rax
addq $0x4, %rax
movq %rax, -0x18(%rbp)
movl -0x1c(%rbp), %esi
callq 0x43a0
movl -0x1c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
jmp 0x296f
movq -0x10(%rbp), %rax
movq %rax, -0x50(%rbp)
cmpq $0x0, %rax
je 0x29c0
movq -0x50(%rbp), %rdi
callq 0x4410
movq -0x50(%rbp), %rdi
movl $0x4, %esi
callq 0x21b0
movq -0x8(%rbp), %rax
movq %rax, -0x68(%rbp)
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
seto %cl
addq $0x8, %rdi
setb %al
orb %al, %cl
movq $-0x1, %rax
testb $0x1, %cl
cmovneq %rax, %rdi
movq %rdi, -0x70(%rbp)
callq 0x2030
movq %rax, %rcx
movq -0x68(%rbp), %rax
movq %rcx, -0x60(%rbp)
movq %rax, (%rcx)
addq $0x8, %rcx
movq %rcx, -0x58(%rbp)
cmpq $0x0, %rax
je 0x2a56
movq -0x58(%rbp), %rax
movq -0x68(%rbp), %rdx
shlq $0x2, %rdx
movq %rax, %rcx
addq %rdx, %rcx
movq %rcx, -0x80(%rbp)
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rdi
movq %rdi, -0x88(%rbp)
callq 0x44a0
jmp 0x2a3e
movq -0x80(%rbp), %rcx
movq -0x88(%rbp), %rax
addq $0x4, %rax
cmpq %rcx, %rax
movq %rax, -0x78(%rbp)
jne 0x2a2c
movq -0x58(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
movq %rax, -0x40(%rbp)
movq 0x656b(%rip), %rdi      # 0x8fd8
leaq 0x362f(%rip), %rsi      # 0x60a3
callq 0x2190
movq %rax, %rdi
movq -0x28(%rbp), %rsi
callq 0x2130
movq %rax, %rdi
leaq 0x3619(%rip), %rsi      # 0x60a8
callq 0x2190
movq %rax, %rdi
movq -0x40(%rbp), %rsi
callq 0x2130
movq %rax, %rdi
movq 0x650e(%rip), %rsi      # 0x8fb8
callq 0x21c0
movl $0x0, -0x44(%rbp)
movslq -0x44(%rbp), %rax
cmpq -0x8(%rbp), %rax
jae 0x2b47
movq -0x40(%rbp), %rdi
movq %rdi, %rax
addq $0x4, %rax
movq %rax, -0x40(%rbp)
movl -0x44(%rbp), %esi
callq 0x43a0
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x2ab6
movq -0x58(%rbp), %rcx
movq %rax, %rsi
movq -0x88(%rbp), %rax
movq %rsi, -0x30(%rbp)
movl %edx, -0x34(%rbp)
cmpq %rax, %rcx
movq %rax, -0x90(%rbp)
je 0x2b35
movq -0x90(%rbp), %rdi
addq $-0x4, %rdi
movq %rdi, -0x98(%rbp)
callq 0x4410
movq -0x58(%rbp), %rcx
movq -0x98(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0x90(%rbp)
jne 0x2b07
movq -0x70(%rbp), %rsi
movq -0x60(%rbp), %rdi
callq 0x2350
jmp 0x2c30
movq 0x648a(%rip), %rdi      # 0x8fd8
leaq 0x354e(%rip), %rsi      # 0x60a3
callq 0x2190
movq %rax, %rdi
movq -0x28(%rbp), %rsi
callq 0x2130
movq %rax, %rdi
leaq 0x3538(%rip), %rsi      # 0x60a8
callq 0x2190
movq %rax, %rdi
movq -0x40(%rbp), %rsi
callq 0x2130
movq %rax, %rdi
movq 0x642d(%rip), %rsi      # 0x8fb8
callq 0x21c0
movq -0x28(%rbp), %rax
movq %rax, -0xa0(%rbp)
cmpq $0x0, %rax
je 0x2c27
movq -0xa0(%rbp), %rcx
movq %rcx, %rax
addq $-0x8, %rax
movq %rax, -0xb8(%rbp)
movq -0x8(%rcx), %rdx
movq %rdx, -0xb0(%rbp)
shlq $0x2, %rdx
movq %rcx, %rax
addq %rdx, %rax
cmpq %rax, %rcx
movq %rax, -0xa8(%rbp)
je 0x2c0c
movq -0xa8(%rbp), %rdi
addq $-0x4, %rdi
movq %rdi, -0xc0(%rbp)
callq 0x4410
movq -0xa0(%rbp), %rcx
movq -0xc0(%rbp), %rax
cmpq %rcx, %rax
movq %rax, -0xa8(%rbp)
jne 0x2bdb
movq -0xb8(%rbp), %rdi
movq -0xb0(%rbp), %rsi
shlq $0x2, %rsi
addq $0x8, %rsi
callq 0x2350
addq $0xc0, %rsp
popq %rbp
retq
movq -0x30(%rbp), %rdi
callq 0x2300
nopl (%rax)