progC.pdf progC-s.pdf progC-e.pdf 記事一覧 |
|
簡単な継承の例です.
/* --- p2.cpp (半角 < を全角 < で置換)--- */
#include <stdio.h>
typedef struct tnode{
int d; struct tnode *l, *r;
tnode(void){d = 0; l = r = NULL;}
tnode(int d0){tnode( ); d = d0;}
void add(int k){d += k;}
} tnode;
struct tnode1: tnode{
char *s;
tnode1(void): tnode(5){s = "xy";}
tnode1(int d0, char *s0): tnode(d0){
s = s0;
}
};
int main( ){
char s1[8]="abc";
tnode t(1); tnode1 t1(2, s1);
tnode1 *a1; a1 = new tnode1[4]; //tnode1(void) がないとエラー
//
t.add(3); printf("%d\n", t.d);
t1.add(4); printf("%d, %s\n", t1.d, t1.s);
printf("%d, %s\n", a1[0].d, a1[0].s);
a1[2] = t1; printf("%s\n", a1[2].s);
delete[] a1;
printf("%d, %s\n", a1[0].d, a1[0].s); //直後だから上書きされていない
//
tnode *p=&t; tnode1 *p1=&t1;
printf("p->d == %d\n", p->d);
printf("p1->d == %d\n", p1->d);
p = p1; printf("p->d == %d\n", p->d);
//p1 = p; //当然エラー
//p1 = (void)p; //これもエラー
p1 = (tnode1*)(int)p; //エラーにならない!(ブログ:2014-01-28)
p->d = 5; printf("p1->d == %d\n", p1->d);
//
printf("OK?\n");
return 0;
}
参考資料([n]は本文でも引用, *.pptはブロック解除が面倒なので未調査):
[1] メモリの二重解放回避テク - akihiko's tech note
http://d.hatena.ne.jp/aki-yam/20081205/1228490763
メモリを解放した後 (delete p1;),ほかの用途でメモリを確保し (p2=new T;),たまたまそれが解放したメモリと同じアドレスに割り当てられてしまった場合 (p1==p2),最初のメモリを二重解放すると (delete p1;),新しく確保したメモリ (p2) が解放されてしまう.この結果,新しく確保したメモリにアクセスすると値が書き換えられていたり,
セグメンテーションフォルトが発生する場合がある.プログラマはまず,新しく確保したメモリ (p2) に問題があることを疑うが,実は最初のメモリ (p1) の解放に問題があるという,大変デバッグしにくい問題に直面するのだ.
[2] C/C++のちょっとしたこと
http://www.geocities.jp/chiakifujimon/pghint/c.html
これは、C/C++の文字列の特性をしっかり把握していないときに起こしてしまう典型的なエラーです。
※ 上例は無関係
※コメント投稿者のブログIDはブログ作成者のみに通知されます