【C++】オブジェクトの代入
「オブジェクト1=オブジェクト2」のような書き方で代入できる。
study79.cpp
#include <iostream> using namespace std; class myclass { int a, b; public: void set( int i, int j ) { a = i; b = j; } void show() { cout << a << ' ' << b << "\n"; } }; int main () { myclass o1, o2; o1.set( 10, 4 ); o2 = o1; o1.show(); o2.show(); return 0; }
$ g++ -o study79 study79.cpp $ ./study79 10 4 10 4
study80.cpp
このプログラムはコンパイルエラーになる。
#include <iostream> using namespace std; class myclass { int a, b; public: void set( int i, int j ) { a = i; b = j; } void show() { cout << a << ' ' << b << "\n"; } }; class yourclass { int a, b; public: void set( int i, int j ) { a = i; b = j; } void show() { cout << a << ' ' << b << "\n"; } }; int main () { myclass o1; yourclass o2; o1.set( 10, 4 ); o2 = o1; o1.show(); o2.show(); return 0; }
クラスの中身が同じでもクラス名が同じでないと代入できない。
study82.cpp
このプログラムはコアダンプになる。
#include <iostream> #include <cstring> #include <cstdlib> using namespace std; class strtype { char *p; int len; public: strtype( char *ptr) { len = strlen( ptr ); p = ( char * ) malloc( len + 1 ); if( !p ) { cout << "メモリ割り当てエラー\n"; exit(1); } strcpy( p, ptr ); } ~strtype() { cout << "pを開放する\n"; free( p ); } void show() { cout << p << " - 長さ:" << len << "\n"; } }; int main() { strtype s1("This is a test"), s2("I like C++"); s1.show(); s2.show(); s2 = s1; s1.show(); s2.show(); return 0; }
$ g++ -o study82 study82.cpp $ ./study82 This is a test - 長さ:14 I like C++ - 長さ:10 This is a test - 長さ:14 This is a test - 長さ:14 pを開放する pを開放する *** Error in `./study82': double free or corruption (fasttop): 0x0000000000e2ac20 *** ======= Backtrace: ========= /lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7fe0ad0767e5] /lib/x86_64-linux-gnu/libc.so.6(+0x8037a)[0x7fe0ad07f37a] /lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7fe0ad08353c] ./study82[0x400c64] ./study82[0x400b1b] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0)[0x7fe0ad01f830] ./study82[0x4009b9] ======= Memory map: ======== 00400000-00401000 r-xp 00000000 08:06 14298065 /home/atsuya/study/cpp/study82 00601000-00602000 r--p 00001000 08:06 14298065 /home/atsuya/study/cpp/study82 00602000-00603000 rw-p 00002000 08:06 14298065 /home/atsuya/study/cpp/study82 00e19000-00e4b000 rw-p 00000000 00:00 0 [heap] 7fe0a8000000-7fe0a8021000 rw-p 00000000 00:00 0 7fe0a8021000-7fe0ac000000 ---p 00000000 00:00 0 7fe0accf6000-7fe0acdfe000 r-xp 00000000 08:06 13238541 /lib/x86_64-linux-gnu/libm-2.23.so 7fe0acdfe000-7fe0acffd000 ---p 00108000 08:06 13238541 /lib/x86_64-linux-gnu/libm-2.23.so 7fe0acffd000-7fe0acffe000 r--p 00107000 08:06 13238541 /lib/x86_64-linux-gnu/libm-2.23.so 7fe0acffe000-7fe0acfff000 rw-p 00108000 08:06 13238541 /lib/x86_64-linux-gnu/libm-2.23.so 7fe0acfff000-7fe0ad1bf000 r-xp 00000000 08:06 13238538 /lib/x86_64-linux-gnu/libc-2.23.so 7fe0ad1bf000-7fe0ad3bf000 ---p 001c0000 08:06 13238538 /lib/x86_64-linux-gnu/libc-2.23.so 7fe0ad3bf000-7fe0ad3c3000 r--p 001c0000 08:06 13238538 /lib/x86_64-linux-gnu/libc-2.23.so 7fe0ad3c3000-7fe0ad3c5000 rw-p 001c4000 08:06 13238538 /lib/x86_64-linux-gnu/libc-2.23.so 7fe0ad3c5000-7fe0ad3c9000 rw-p 00000000 00:00 0 7fe0ad3c9000-7fe0ad3e0000 r-xp 00000000 08:06 13242862 /lib/x86_64-linux-gnu/libgcc_s.so.1 7fe0ad3e0000-7fe0ad5df000 ---p 00017000 08:06 13242862 /lib/x86_64-linux-gnu/libgcc_s.so.1 7fe0ad5df000-7fe0ad5e0000 r--p 00016000 08:06 13242862 /lib/x86_64-linux-gnu/libgcc_s.so.1 7fe0ad5e0000-7fe0ad5e1000 rw-p 00017000 08:06 13242862 /lib/x86_64-linux-gnu/libgcc_s.so.1 7fe0ad5e1000-7fe0ad75d000 r-xp 00000000 08:06 6686331 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25 7fe0ad75d000-7fe0ad95d000 ---p 0017c000 08:06 6686331 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25 7fe0ad95d000-7fe0ad967000 r--p 0017c000 08:06 6686331 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25 7fe0ad967000-7fe0ad969000 rw-p 00186000 08:06 6686331 /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.25 7fe0ad969000-7fe0ad96d000 rw-p 00000000 00:00 0 7fe0ad96d000-7fe0ad993000 r-xp 00000000 08:06 13238524 /lib/x86_64-linux-gnu/ld-2.23.so 7fe0adb3f000-7fe0adb45000 rw-p 00000000 00:00 0 7fe0adb91000-7fe0adb92000 rw-p 00000000 00:00 0 7fe0adb92000-7fe0adb93000 r--p 00025000 08:06 13238524 /lib/x86_64-linux-gnu/ld-2.23.so 7fe0adb93000-7fe0adb94000 rw-p 00026000 08:06 13238524 /lib/x86_64-linux-gnu/ld-2.23.so 7fe0adb94000-7fe0adb95000 rw-p 00000000 00:00 0 7ffe7c6d7000-7ffe7c6f9000 rw-p 00000000 00:00 0 [stack] 7ffe7c7ac000-7ffe7c7af000 r--p 00000000 00:00 0 [vvar] 7ffe7c7af000-7ffe7c7b1000 r-xp 00000000 00:00 0 [vdso] ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall] Aborted (core dumped)
- s1とs2を作成するときに、両者とも文字列を格納するためのメモリを割り当てる
- メモリのポインタ変数pに保存される
- strtypeオブジェクトを破棄するときにメモリが開放される
- s1にs2を代入すると、s2はs1と同じメモリを指すようになる
- そのため、s1オブジェクトを2度開放しようとする
- s2のpがメモリを示したポインタは開放されない これらの理由でコアダンプとなる。
そのため、オブジェクトを代入するときは注意が必要。