【良い文章を共有する】C/C++メモリと実行時の研究
50696 ワード
C/C++ [ Jean.Love]
-----------------------------------------------------------------------------------
( )
( )
( )
( )
( )
( )
( )
( )
( )
( )
( )
( )const
( )
( ) STL
( )
( )
( )new/delete
( )
( )
x<y x-y<0 ?? 。
#include<stdio.h>
int main(void){
int x=1;
unsigned int y=2;
int b=x<y;
int b2=(x-y<0);
printf("%d,%d/n",b,b2);
return 0;
}
?
1,0
, ,x<y x-y<0 !
(1)x<y , y , x , x<y , 1
(2)x-y , 0xfffffffe, 0 , <0 , 0。
, , , , 2 cpu , (<,>,==) , , 2 。 signed unsigned , 。
#include<stdio.h>
int main(void){
int i=-2;
unsigned j=1;
if(j+i>1) // uint
printf("sum=%d/n",j+i);// %d ,j+i 。
return 0;
}
> ./a.out
sum=-1
#include<stdio.h>
int main(void){
int i=-4;
unsigned int j=1;
int ii=i+j;
unsigned int jj=i+j;
printf("%d,%ud/n",ii,jj);
if(ii>1){printf("100000");}
if(jj>1){printf("100001");}
return 0;
}
gcc -S , if(ii>1) if(jj>1) jle jbe。
: int unit , 。
( )
IEEE 。 Linux atoi,ltoi,itoa , VC , ANSI C , *nix sprintf 。IEEE 32 float , 1bit ,8bit ,23bit 。 , 4 , , 。 x86 , > , 。
-0.875, 1( ), -0.111, 1-2 -1.11 x 2^-1, -1, 128 1111111(127), 8 bit , 。 23bit 11000000000000000000, -1.11 , 0。
,-0.875f 2 10111111011000000000000000000000。
#include<stdio.h>
#include<stdlib.h>
void pfloat(float f){
int i,j;
char buf[4][9];
char* p=(char*)&f;
printf("before loop/n");
for(i=0;i<4;++i){
for(j=0;j<8;++j){
buf[i][j]=(p[i]&(0x80>>j))>0?'1':'0';
}
buf[i][8]='/0';
}
for(i=3;i>=0;i--){
printf("%s",buf[i]);
}
printf("/n");
printf("end loop/n");
}
int main(void){
float d1=-0.875;
pfloat(d1);
return 0;
}
。 。 , , , 。 , > 。 32 , float 4 , 23 , 10 9 。
float f1=3.14;
float f2=1e20;
float f3=-1e20;
printf("%d,%f/n",i,f);
printf("%f/n",f1+f2+f3);
printf("%f/n",f2+f3+f1);
printf , 0, 3.14。
float k=1.3456789;
float k2=k;
k-=1000000.0;
printf("%f/n",k);
k+=1000000.0;
printf("%f/n",k);
int b=(k==k2);
printf("%d/n",b);
? b=0, k , 5 , k k2。 k==k2 , , double--52 , 10 16 , 。
double d1,d2;
printf("%f/n",d1);
d1=d2=1.3456789;
d2+=1000000.0;
printf("%f/n",d2);
d2-=1000000.0;
printf("%f/n",d2);
d==d2 。 , 。#define fequals(a,b) fabs(a-b)<0.01f
,printf
float nan=3.0f/0.0f;
printf("%f/n",nan);
inf, , -inf。
( )
(x86 ) ? 。 。
$ cat stk.c
#include<stdio.h>
#include<stdlib.h>
int main(void){
int x=0;
int y=0;
int z=0;
int *p=&y;
*(p+1)=2;// x z? cpu
int* px=(int*)malloc(sizeof(int));
int* py=(int*)malloc(sizeof(int));
int* pz=(int*)malloc(sizeof(int));
*px=1;
*py=1;
*pz=1;
*(py+1)=3;
printf("%d,%d,%d/n",x,y,z);
printf("%p,%p,%p/n",px,py,pz);
printf("%d,%d,%d/n",*px,*py,*pz);
free(px);
free(py);
free(pz);
return 0;
}
$ gcc stk.c && ./a.out
2,0,0
0x9e8b008,0x9e8b018,0x9e8b028
1,1,1
(1)
int* px=(int*)malloc(sizeof(int)*3);
int* py=(int*)malloc(sizeof(int)*3);
int* pz=(int*)malloc(sizeof(int)*3);
printf
0x9e8b008,0x9e8b018,0x9e8b028
? malloc , , 。 。
, Linux x86
---------------------
0xffffffff
->OS , 1/4
0xc000000
->stack ,
| x
| y ->int*(&y)+1 x
| z
->
0x40000000
-> ,
| pz
。。。。。。
| py -> py , *(py+1)=3;
。。。。。。
| px ->malloc
。。。。。。
-> ( )
-> ( , )
0x08048000 -> ,
->
0x00000000
---------------------
*(py+4)=3;
1,1,3
pz 。 。
( )
? ?
$ cat f.c
#include<stdio.h>
int i=0;
void f()
{
printf("%d/n",i);
}
$ cat m.c
int i=3;
extern void f();
int main(void){
f();
return 0;
}
, :
$ gcc -o main m.o f.o
f.o:(.bss+0x0): multiple definition of 'i'
m.o:(.data+0x0): first defined here
collect2: ld 1
, i, i , nm :
$ nm m.o f.o
m.o:
U f
00000000 D i
00000000 T main
f.o:
00000000 T f
00000000 B i
U printf
:
1. m.c int i=3 main , :
$ cat mcp.c
extern void f();
int main(void){
int i=3;
f();
return 0;
}
[zhang@localhost kg]$ nm mcp.o
U f
00000000 T main
m.o i, 。
2. f.c int i static ,
$ cat fcp.c
#include<stdio.h>
static int i=0;
void f(){
printf("%d/n",i);
}
[zhang@localhost kg]$ nm fcp.o
00000000 T f
00000000 b i -> i B b
U printf
main 0, f i i, m.c i。 i , 。
( )
Bus error? , long ,cpu %4/%8 , :
#include<stdio.h>
int main(void){
char buf[8]={'a','b','c','d','e','f'};
char *pb=&(buf[1]); // pb 4bytes 8bytes ,
int *pi=(int*)pb;
printf("%d/n",*pi);
return 0;
}
CPU , CPU 。 。 Sparc(solaris+CC) x86(vc6.0) : Sparc (Bus error (core dumped)),x86 。
Plus: hp pa-risc(aCC),itanium(aCC),IBM(xlC) power
power core dump, pa-risc Itanium core dump.
( )
, 。C++ STL functional ,C 。
#include <stdio.h>
#include <stdlib.h>
typedef void callback(int i);
void p(int i){printf("function p/n");}
void f(int i,callback c){c(i);}
int main(void)
{
f(20,p);
return 0;
}
> ./a.out
function p
, ? f , , f , f callback* 。 。
( )
C++ , public,private 。 。 winXP+gcc3.4.2 0, 。 , ,C++ 。
/*----------------------------------------------------------------------------*/
#include<stdio.h>
class B{
int x;
virtual void f(){printf("f/n");}
virtual void g(){printf("g/n");}
virtual void h(){printf("h/n");}
public:
explicit B(int i) {x=i;}
};
typedef void (*pf)();
int main(void){
B b(20);
int * pb=(int*)&b;
printf("private x=%d/n",pb[1]);
pf *pvt=(pf*)pb[0];//
pf f1=(pf)pvt[0];
pf f2=(pf)pvt[1];
pf f3=(pf)pvt[2];
(*f1)();
(*f2)();
(*f3)();
printf("pvt[3]=%d/n",pvt[3]);//
return 0;
}
private x=20
f
g
h
pvt[3]=0
,b dword, , 。 , b dword, dword
, ,gcc2.95.2 , , pvt= ((int*)(&b))[1] , pvt[0]=0 ,pvt[1] 。 。 , , , coredump。 C++ C++ , , ( ) 。
? 。
#include<string>
using namespace std;
struct a{
int x;
virtual void f(){printf("f(),%d/n",x);}
explicit a(int xx){x=xx;}
};
int main(void){
a a1(2);
a a2(3);
int* pi=(int*)&a1;
int* pvt=(int*)pi[0];
typedef void(*pf)();
pf p=(pf)pvt[0];
(*p)();
int *p2=(int*)&a2;
int *pv2=(int*)p2[0];
pf px=(pf)pv2[0];
(*px)();
return 0;
}
?
$ g++ r.cpp &&./a.out
f(),3
f(),3
? this , this , 。 ? this :
#include<stdio.h>
struct a{
int x;
virtual void f(){printf("f(),%d/n",x);}//............
explicit a(int xx){x=xx;}
};
int main(void){
a a1(2);
a a2(3);
int* pi=(int*)&a1;
int* pvt=(int*)pi[0];
typedef void(*pf)(a*);
pf p=(pf)pvt[0];
(*p)(&a1);
int *p2=(int*)&a2;
int *pv2=(int*)p2[0];
pf px=(pf)pv2[0];
(*px)(&a2);
return 0;
}
> g++ p.cpp && ./a.out
f(),2
f(),3
。
,this C++ , 。 OwnWaterloo , 。
(1)gcc3.4.x , this , :
/*----------------------------------------------------------------------------*/
class C {
int i_;
public:
explicit C(int i) :i_(i) {}
virtual ~C() {}
virtual void f() { printf("C::f(%d)/n",i_); }
};
#if defined(__GNUC__)
#if __GNUC__!=3
#error not test on other gcc version except gcc3.4
#endif
#include <assert.h>
#include <string.h>
#include <stdio.h>
#define intprt_t int*
int main()
{
C c1(1212);
C c2(326);
typedef void (* virtual_function)(C*);
// gcc , this
// virtual_function C
struct
{
virtual_function* vptr;
//
// , , RTTI
// , , “ ”
int i;
// data member
} caster;
// , gcc 。
memcpy(&caster,&c1,sizeof(caster));
printf("c1.i_ = %d/n",caster.i); // 1212
printf("c1.vptr_ = %p/n"
,reinterpret_cast<void*>(reinterpret_cast<intptr_t>(caster.vptr)) );
virtual_function* vptr1 = caster.vptr;
memcpy(&caster,&c2,sizeof(caster));
printf("c2.i_ = %d/n",caster.i);
printf("c2.vptr_ = %p/n",(void*)caster.vptr);
virtual_function* vptr2 = caster.vptr;
assert(vptr1==vptr2);
// , C, vptr
vptr1[2](&c1); // C::f(1212)
vptr2[2](&c2); // C::f(326)
/* f 2 。 ~C 1 。*/
/* , 0 。 ~C , f 1 。*/
}
(2)MSVC
int main()
{
C c1(1212);
C c2(326);
typedef void (__stdcall* virtual_function)(void);
// msvc ecx this,
// , msvc ,
// __stdcall
struct {
virtual_function* vptr;
int i;
} caster;
//
memcpy(&caster,&c1,sizeof(caster));
printf("c1.i_ = %d/n",caster.i); // 1212
virtual_function* vptr1 = caster.vptr;
printf("c1.vptr_ = %p/n"
,reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(vptr1)) );
memcpy(&caster,&c2,sizeof(caster));
printf("c2.i_ = %d/n",caster.i); // 326
virtual_function* vptr2 = caster.vptr;
printf("c2.vptr_ = %p/n"
,reinterpret_cast<void*>(reinterpret_cast<ptrdiff_t>(vptr2)) );
assert(vptr1==vptr2);
// c1 c2 C,
// , , this
//vptr1[2]();
//
//_asm { lea ecx, c1 }
// , ecx
// vptr1[2]();
//
virtual_function f1 = vptr1[1];
_asm {
lea ecx,c1
call f1
}
virtual_function f2 = vptr2[1];
_asm {
lea ecx,c2
call f2
}
// C::f(1212),C::f(326)
// , C::f 1 , vs watch ……
}
( )
, 。 :(gcc -masm=hello -S main.cpp )
#include<stdio.h>
int x=3;
int f1(){return x;}
int& f2(){return x;}
int main(){
int a=f1();
int y=f2();
y=4;// x=3
int&z=f2();
z=5;
printf("x=%d,y=%d",x,y);//z x
return 0;
}
? x=5,y=4
:
f2 , int&z =f2() ,int y=f2() 。 ( )
-----------------------------------------------------------------------------------
f1 f2 :
.globl __Z2f1v
.def __Z2f1v; .scl 2; .type 32; .endef
__Z2f1v:
push ebp
mov ebp, esp
mov eax, DWORD PTR _x f1()
pop ebp
ret
.align 2
.globl __Z2f2v
.def __Z2f2v; .scl 2; .type 32; .endef
__Z2f2v:
push ebp
mov ebp, esp
mov eax, OFFSET FLAT:_x f2() ,
pop ebp
ret
.def ___main; .scl 2; .type 32; .endef
.section .rdata,"dr"
main
_main:
push ebp
mov ebp, esp
sub esp, 40
and esp, -16
mov eax, 0
add eax, 15
add eax, 15
shr eax, 4
sal eax, 4
mov DWORD PTR [ebp-16], eax
mov eax, DWORD PTR [ebp-16]
call __alloca
call ___main
call __Z2f1v -> f1(), eax
mov DWORD PTR [ebp-4], eax -> eax a
call __Z2f2v
mov eax, DWORD PTR [eax] -> f2(), x eax
mov DWORD PTR [ebp-8], eax -> eax y
mov DWORD PTR [ebp-8], 4 -> "4" y. y x!!!!!!
call __Z2f2v
mov DWORD PTR [ebp-12], eax -> f2(), x z
mov eax, DWORD PTR [ebp-12] -> x eax
mov DWORD PTR [eax], 5 -> 5 eax x
mov eax, DWORD PTR [ebp-8] // printf
mov DWORD PTR [esp+8], eax
mov eax, DWORD PTR _x
mov DWORD PTR [esp+4], eax
mov DWORD PTR [esp], OFFSET FLAT:LC0
call _printf
mov eax, 0
leave
ret
.def _printf; .scl 2; .type 32; .endef
( )
, ,
#include<stdio.h>
struct A {int x;int y; };
struct B : virtual public A {
int a;
B(){x=1;y=2;a=55;}
};
struct C : virtual public A {
int b;
C(){x=3;y=4;b=66;}
};
struct D : public B, public C { };
int main(void) {
A a;
B b;
C c;
D d;
D *pd = &d;
C *pd_c =(C*)(&d);
B *pd_b =(B*)(&d);
A *pd_a =(A*)(&d);
printf("%d,%d,%d,%d/n",sizeof(a),sizeof(b),sizeof(c),sizeof(d));
printf("%p,%p,%p,%p/n",pd,pd_c,pd_b,pd_a);
int *pd2=(int*)pd;
printf("%p,%d,%p,%d,%d,%d/n",**((int**)(pd2)),*(pd2+1),**((int**)(pd2+2)),*(pd2+3),*(pd2+4),*(pd2+5));
return 0;
}
8,16,16,24
0022FF20,0022FF28,0022FF20,0022FF30
00000008,55,00000000,66,3,4
:D ( ),vbptr
|A.y|
|A.x|
|C.b|
|C.vbptr|
|B.a|
|B.vbptr|
bvptr virtual public , 。 C.vbptr=0,B.vbptr=8. d ,C::C() B::B() , (x,y)=(3,4)
D (8,55,0,66,3,4)
( )
(1)ctor,dtor atexit
#include<stdio.h>
#include<stdlib.h>
class a{
int ii;
public:
explicit a(int i){
++count;
ii=i;
printf("ctor i=%d/n",ii);
atexit(f);
}
~a(){printf("dtor i=%d/n",ii);}
static void f(){printf("f() count=%d/n",count);}
static int count;
};
int a::count=0;
void g(){
a a2(2);// , a , N a N !!
printf("after g() a ctor/n");
}
a a3(3);//
int main(void){
a a1(1);//
atexit(g);
return 0;
}
./a.out
ctor i=3
ctor i=1
dtor i=1
ctor i=2
after g() a ctor
dtor i=2
f() count=3
f() count=3
dtor i=3
f() count=3
(2) bss 、data 、text 。 , , 。 , , 。
( intel 80x86 ),bss (Block Started by Symbol segment) , bss 。bss , 。
, C , .data , .bss 。
《Programming ground up》 .bss :There is another section called the .bss. This section is like the data section, except that it doesn’t take up space in the executable.
text data ( ), ; bss , 。
: (windows+cl)
1:
int ar[30000];
void main() ......
2:
int ar[300000] = {1, 2, 3, 4, 5, 6 };
void main() ......
2 .exe 1 。 1.asm ar :
_BSS SEGMENT
?ar@@3PAHA DD 0493e0H DUP (?) ; ar
_BSS ENDS
2.asm ,ar :
_DATA SEGMENT
?ar@@3PAHA DD 01H ; ar
DD 02H
DD 03H
ORG {1}1199988
_DATA ENDS
, .bss , .data , : .bss , ; .data ; ( ,cl 0xCCCCCCCC) 。.bss .exe , ( ); .data , , 。
(3) : strcpy , :
#include<stdio.h>
#include<string.h>
#include<ctype.h>
void f(char* s){
int len=strlen(s);
char buf[len+1];
strcpy(buf,s);
printf("s=%s,buf=%s/n",s,buf);
strcpy(s,buf);
printf("after strncpy/n");
}
int main(void){
f("abc");
return 0;
}
./a.out
s=abc,buf=abc
main
char b[]="abc";//
f(b);
。
: “abc” , strcpy
, , strcpy 。
(4) ( ), ,
#include<stdio.h>
class c{
public:
c(){printf("ctor/n");}
};
int main(void){
int i=10;
while(i--){
c c1;
}
return 0;
}
"ctor" 10
( )
C/C++ , 。
( )
void f(char* buf); | void f(char* buf);
int main(...){ | int main(...){
char buf[]="abc"; | char* pbuf="abc";
f(buf); | f(pbuf); ->
buf[2]='x'; | pbuf[2]='x' ->
? :
(1) , , f(buf)
char* pbuf="abc",f(pbuf) 。
(2) :
buf[2] (buf +2), x
pbuf[2] pbuf , pbuf , ,+2, x
,pbuf 2 , buf[2] 。
--------------------------------------------------------------
,** ?
int main(...){
int buf[2][3];// buf 1 !
buf[10][10]=6; ? buf ,10 10 ,buf[1][2] :
(1*10)+ 3 (2), ((int*)(buf))[12]。
, buf , ? , ,2 , :
void f(int buf[][10]){
buf[1][2]=6;// f buf[1][2] buf 。
...
void f(int buf[10][10]) void f(int buf[20][10]) 。 , ,( ), , 。
--------------------------------------------------------------
f f(int buf[][]) ? f(int *buf[]) f(int ** ppbuf) , 2 。
int** buf=new int*[10];
for(int i=0;i<10;++i)buf[i]=new int[10];
f(buf);
buf ,buf[1][2] :
(a) buf[1]
(b) , , 2 。
f(int buf[][10]) f(int buf[][]), :
void f2(int ppi[][2]){}
void f3(int *ppi[2]){}
int p2[3][2]={ {1,2},{3,4}, };
f2(p2);
f3(p2); : 1 ( ‘f3’) 。
f3 2 , p2 , , , 。
, 。
int main(void)
{
int arr[2][3] = {
{0,1,3},
{4,5,6}
};
int i1=(int)arr;
int i2=(int)(arr+1);
printf("i2-i1=%d/n",i2-i1);
printf("%x/n",arr+1);
printf("%x/n",*(arr+1));
printf("%d/n",**(arr+1)));
return 0;
}
, :《C 》
( )const
(1) const ?
char * const cp; ( * pointer to ) const char* p
cp is a const pointer to char
const char * p;
p is a pointer to const char;
, , thinking in C++
(2)const :
,const const 。 :
> cat t.cpp
struct a{
int x;
bool operator==(const a& ia){return x==ia.x;}// !!!!!!!!
};
bool f(const a& ia, const a& ib){
return ia==ib;// == const a&, operator== const
}
int main(int argc, char *argv[]){
return 0;
}
:
bool operator==(const a& ia) const {return x==ia.x;}
f a const , operator== , , == const 。
( )
(1) C
> cat t.cpp
#include<stdio.h>
struct e{// 3
int x;
int y;
e& operator=(const e& ie){*this=ie;}
~e(){}
};
int main(void){
e buf[]={// {}
{1,2},
{1,3},
{1,4}
};
printf("%d %d %d/n",buf[0].y,buf[1].y,buf[2].y);
return 0;
}
, e , 。
: public , C ( ), C
(2) static , static
#include<stdio.h>
struct B{
void inc(){
static int i=0;
printf("%d/n",++i);
}
};
int main(void){
B b1,b2;
b1.inc();
b2.inc();
}
> ./a.out
1
2
(3)explicit
class i{
public:
int* a;int b;
i(int* x){ printf("ctor/n"); a=x; }
i(const i& ii){printf("copy ctor/n");a=ii.a;}
explicit i(){printf("ctor default/n");}
i& operator=(const i& ii){printf("operator/n"); a=ii.a;}
};
int main(int argc, char *argv[]){
i i1;
int x=20;
int *b=&x;
i1=b;
printf("i1.a=%d,p=%d/n",*(i1.a),i1.a);
return 0;
}
ctor default
ctor
operator
i1.a=20,p=2293596
int* b=&x i i1=b,
explicit i()... explicit , ?
: explicit ( , , )
(4)dynamic_cast :
dynamic_cast , , ( ),RTTI 。
#include <cstdlib>
#include <cstdio>
#include <typeinfo>
using namespace std;
class A{};
class C{
public:
virtual void g(){}
};
class D:public C{};
int main(int argc, char *argv[])
{
D d ;
A *a=(A*)&d;
C* pa=(C*)a;
C& pc=*pa;
try{
C& pc2=dynamic_cast<C&>(pc);
D& pd=dynamic_cast<D&>(pc);
}catch(bad_cast){
printf("bad_cast/n");
}catch(...){
printf("other exception/n");
}
return EXIT_SUCCESS;
}
。 "D d" "C d" ,"D& pd=dynamic_cast<D&>(pc)" std::bad_cast
Plus:
dynamic_cast , NULL, bad_cast
(5)union struct plain old data, ctor,dtor,operator=
(6)#define , , , 。C++ enum , const , , 。
#define MONDAY 1
class b{
public:
const static int i=0;//if not const, compile error
enum{friday=5};//equal to const int
};
const char* buf="abc";
int main(void){
buf="xyz";
int x=b::friday;
int y=MONDAY;
return 0;
}
Plus: static , const , const 。
( ) STL
(1)
, , STL , 。
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iterator>
#include<iostream>
using namespace std;
class array{
int * pi;
public:
array(){
pi=new int[5];
pi[0]=3;
pi[1]=44;
pi[2]=5;
pi[3]=1;
pi[4]=26;
}
virtual ~array(){ if(pi){delete[] pi;pi=0;} }
class Iter{//
int* data;
public:
Iter(int* i){data=i;}
Iter(){data=0;}
Iter& operator=(const Iter& i){data=i.data;}
bool operator!=(const Iter& i){return data!=i.data;}
int operator*(){return *data;}
void operator++(){++data;}
void operator--(){--data;}
};
Iter begin(){return Iter(π[0]);}
Iter end(){return Iter(π[5]);}
};
int main(int argc, char *argv[])
{
array l;
array::Iter it;
for(it=l.begin();it!=l.end();++it){cout<<*it<<' ';}
cout<<'/n';
//copy(l.begin(),l.end(),ostream_iterator<int>(cout, " ")); // ,
return 0;
}
-> :
"copy(l.begin(),l.end(),ostream_iterator<int>(cout, " ")); " ,
-> :
, :iterator_category, value_type, difference_type, distance_type, pointer, reference, :(1) (2) std::iterator
《C++ ( )》 :
“ int * int[] , list<int>::iterator list ” , 。iterator_traits .
(2)ostream_iterator, cout , <<
#include<algorithm>
#include<iterator>
#include<iostream>
using namespace std;
struct e {
float v;char c;
operator float()const {return v;}
//operator char() const {return c;}
//should conflict with operator float()
};
int main(int argc, char *argv[])
{
int l=4; e p[]={ {1.5,'x'}, {0.5,'a'}, {1.2,'b'}, {0.7,'y'} };
copy(p,p+l,ostream_iterator<e>(cout," "));
cout<<'/n';
return 0;
}
operator float() operator char() ,
(3)friend
, singleton, ctor,dtor,copyctor,"=" ctor private, instance。 , auto_ptr , 。
class s{
static auto_ptr<s> pInst;
s(){}
~s(){}
s(const s& os){printf("s.copy ctor/n");}
s& operator = (const s& os){printf("s.operator= called/n");}
public:
static s& getInst(){
if(pInst.get()==0)
pInst.reset(new s());
return *pInst;
}
};
auto_ptr<s> s::pInst;
, auto_ptr delete <s>, s , s
friend class auto_ptr<s>;
。 auto_ptr, atexit , 。
(4) class Iter:public std::iterator<bidirectional_iterator_tag, int>
copy(l.begin(),l.end(),ostream_iterator<int>(cout, " "));
:
:iterator_category, value_type, difference_type, distance_type, pointer, reference, :
1.
2. std::iterator
( )
STL , ? ( ) ? iterator_traits , iterator , 。( typedef )
stl::iterator_traits : typedef iterator , http://msdn.microsoft.com/en-us/library/zdxb97eh(VS.80).aspx
template<class Iterator>
struct iterator_traits {
typedef typename Iterator::iterator_category iterator_category;
typedef typename Iterator::value_type value_type;
typedef typename Iterator::difference_type difference_type;
typedef typename Iterator::pointer pointer;
typedef typename Iterator::reference reference;
};
template<class Type>
struct iterator_traits<Type*> {
typedef random_access_iterator_tag iterator_category;//
typedef Type value_type;//---------------> !!!! !!!!
typedef ptrdiff_t difference_type;
typedef Type *pointer;
typedef Type& reference;
};
template<class Type>
struct iterator_traits<const Type*> {
typedef random_access_iterator_tag iterator_category;
typedef Type value_type;
typedef ptrdiff_t difference_type;
typedef const Type *pointer;
typedef const Type& reference;
};
// iterator_traits.cpp
// compile with: /EHsc( VC )
#include <iostream>
#include <iterator>
#include <vector>
#include <list>
using namespace std;
template< class it >
void
function( it i1, it i2 )
{
iterator_traits<it>::iterator_category cat;
cout << typeid( cat ).name( ) << endl;
while ( i1 != i2 )
{
iterator_traits<it>::value_type x;
x = *i1;
cout << x << " ";
i1++;
};
cout << endl;
};
int main( )
{
vector<char> vc( 10,'a' );
list<int> li( 10 );
function( vc.begin( ), vc.end( ) );
function( li.begin( ), li.end( ) );
}
Output:
struct std::random_access_iterator_tag
a a a a a a a a a a
struct std::bidirectional_iterator_tag
0 0 0 0 0 0 0 0 0 0
Plus:
iterator ,
typedef vector<int> vi;
vi v(3);
vi::iterator it=v.begin();
for(it;it!=v.end();++it)*it=9;
copy(v.begin(),v.end(),ostream_iterator<int>(cout,"_"));
( )
(1)typeid , ( )
>cat type.cpp
#include<iostream>
using namespace std;
class Base {
public:
virtual void vvfunc() {}
};
class Derived : public Base {};
using namespace std;
int main() {
Derived* pd = new Derived;
Base* pb = pd;
cout << typeid( pb ).name() << endl; //prints "class Base *"
cout << typeid( *pb ).name() << endl; //prints "class Derived"
cout << typeid( pd ).name() << endl; //prints "class Derived *"
cout << typeid( *pd ).name() << endl; //prints "class Derived"
delete pd;
}
solaris CC
> ./a.out
Base*
Derived
Derived*
Derived
typeid type_info 。 expression , 。 , , , , type_info( ), type_info
(2)static_cast
, (char*) , static_cast<char*>() , 。
#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;
struct s{
char buf[4];
s(){strcpy(buf,"abc");}
operator char*(){return "kkk";}
};
struct c{
char *buf;
c(){buf="xyz";}
};
int main(void){
s s1;
printf("string1 =%s/n",&s1);// , s.buf
c c1;
printf("string2 =%s/n",*((char**)&c1));//
printf("string3 =%s/n",(char*)s1);
cout<<static_cast<char*>(s1)<<'/n';// , (char*)
return 0;
}
(3) :
#include<stdio.h>
class B{// , 。
int x;
virtual void f(){printf("f/n");}
virtual void g(){printf("g/n");}
virtual void h(){printf("h/n");}
public:
explicit B(int i) {x=i;}
};
typedef void (*pf)();
int main(void){
B b(20);
int * pb=(int*)&b;
printf("private x=%d/n",pb[1]);
pf *pvt=(pf*)pb[0];// b ,
pf f1=(pf)pvt[0];
pf f2=(pf)pvt[1];
pf f3=(pf)pvt[2];
(*f1)();
(*f2)();
(*f3)();
printf("pvt[3]=%d/n",pvt[3]);// ,gcc 0
return 0;
}
private x=20
f
g
h
pvt[3]=0
( )new/delete
(1)new delete , 。
new delete
class a{
public:
void* operator new(size_t){
printf("a::new/n");
return ::new a;
}
void* operator new[](size_t l){
printf("a::new[%d]/n",l);
return ::new a[l];
}
void operator delete(void* p){
printf("a::delete/n");
::delete (a*)p;
}
void operator delete[](void* p){
printf("a::delete[]/n");
::delete[] (a*)p;
}
};
int main(void){
a* pa=new a;
delete pa;
pa=new a[2];
delete[] pa;
return 0;
}
> CC t.C && ./a.out
a::new
a::delete
a::new[2]
a::delete[]
(2)replacement new 。
class c{
int x;
public:
explicit c(int ix){x=ix;printf("ctor/n");}
~c(){printf("dtor/n");}
};
int main(void){
try{
char mem[sizeof(c)*2];
c* pc1=new(mem) c(2);
c c3(4); // ,delete pc1 , ...........................................
delete pc1;// delete , ????????
//pc1->~c();// delete 。
}catch(...){
printf("get exception/n");
}
return 0;
}
c* pc1=new(mem) c(2);
delete pc1;// delete , ????????
, new , , free , 。 《C++ ( ) 2 》
(3) , ,new/malloc,delete/free , VC
#if !_VC6SP2 || _DLL
void *__CRTDECL operator new[](size_t count) _THROW1(std::bad_alloc)
{ // try to allocate count bytes for an array
return (operator new(count));
}
#endif /* !_VC6SP2 || _DLL */
_C_LIB_DECL
int __cdecl _callnewh(size_t size) _THROW1(_STD bad_alloc);
_END_C_LIB_DECL
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{ // try to allocate size bytes
void *p;
while ((p = malloc(size)) == 0)
if (_callnewh(size) == 0)
{ // report no memory
static const std::bad_alloc nomem;
_RAISE(nomem);
}
return (p);
}
(4) operator new , , size_t , (delete[] )
new/delete :
#include <new>
#include <cstdio>
#include <cstdlib>
using namespace std;
void* operator new(size_t size) throw(bad_alloc)
{
printf("operator new:%d Byte/n",size);
void* m= malloc(size);
if(!m) puts("out of memory");
return m;
}
void operator delete(void* m)throw(){
puts("operator delete");
free(m);}
class B{
int s;
public:
B(){/*puts("B::B()");*/}
~B(){/*puts("B::~B()");*/}
};
int main(int argc, char* argv[]){
int* p = new int(4);
delete p;
B* s = new B;
delete s;
B* sa = new B[10];
delete []sa;
int* pi=new int[3];
delete []pi;
return 0;
}
> gcc n.C && ./a.out
operator new:4 Byte
operator delete
operator new:4 Byte
operator delete
operator new:48 Byte -> ,new ,4x10 10 , 8 ?
operator new:12 Byte
:
.
:
class B xxxxxxxxxxxxx;
p=new B[num];
( : ):
+--------------------------------------------------------------+
|num|var[0]|var[1]|var[2]|var[3]|........|var[num-1]|
+--------------------------------------------------------------+
push n ;n=num*var_size+4
call new
....................................
push B::~B()
push B::B()
*((int*)p)=num;
((int*)p)++;
push num
push var_size
push p
call vector_constructor_iterator ; B::B(), num
+--------------------------------------------------------------+
,delete ( ,delete []sa;), 。 delete ( , delete []sa), ( new delete )。 , delete 。 , 4 , 。 , new new 4 ( )。 , 。
(5) , new/delete,
void* operator new( size_t size ){
if( 0 == size ) // !!!!
size = 1;
while(1){
size ;
if( )
return ;
new_handler g= set_new_handler(0);
set_new_handler(g);
if( g)(*g)();
else throw std::bad_alloc();
}
}
void operator delete( void* p){
if( 0 == p) //
return;
...
}
new_handler set_new_handler ,newhandler :
void mynewhandler(){
if( operator new )
{
,
return;
}
//
abort/exit
set_new_handler( newhandler 0);
set_new_handler(0)
throw bad_alloc()//
}
( ) ---- C/C++ ,
(1) c
#include<stdio.h>
int main(void){
FILE* pin=fopen("in.data","rb");
FILE* pout=fopen("out.data","wb");
int c;
while((c=fgetc(pin))!=EOF){
fputc(c,pout);}
fclose(pin);
fclose(pout);
return 0;
}
(2)Iostream
#include<iostream>
#include<fstream>
using namespace std;
int main(void){
ifstream fi;
fi.open("in.data",ios::binary);
ofstream fo;
fo.open("out.data",ios::binary);
char buf[1024];
do{
fi.read(buf,sizeof(buf));
fo.write(buf,fi.gcount());
}while(fi.good());
fi.close();
fo.close();
return 0;
}
do-while : fo<<fi.rdbuf()
(3)STL ,
#include<fstream>
#include<iterator>
#include<algorithm>
using namespace std;
int main(void){
ifstream fi;
fi.open("in.data",ios::binary);
ofstream fo;
fo.open("out.data",ios::binary);
copy(istreambuf_iterator<char>(fi),istreambuf_iterator<char>(),ostreambuf_iterator<char>(fo));
fi.close();
fo.close();
return 0;
}