ぼんさい塾

ぼんさいノートと補遺に関する素材や注釈です.ミスが多いので初稿から1週間を経た重要な修正のみ最終更新日を残しています.

広告

※このエリアは、60日間投稿が無い場合に表示されます。記事を投稿すると、表示されなくなります。

g++による演習 (2)

2014-01-29 12:21:58 | 暮らし
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++の文字列の特性をしっかり把握していないときに起こしてしまう典型的なエラーです。
※ 上例は無関係

ジャンル:
学習
コメント   この記事についてブログを書く
« gccによる演習 (12) | トップ | g++による演習 (3) »
最近の画像もっと見る

コメントを投稿