LIFE LOG(ここにはあなたのブログ名)

あつあつ備忘録

ソフトやハード、時にはメカの備忘録をまとめていきます

【C++】オブジェクトの代入

f:id:AtsuyaKoike:20190524095847p:plain:w300

「オブジェクト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)
  1. s1とs2を作成するときに、両者とも文字列を格納するためのメモリを割り当てる
  2. メモリのポインタ変数pに保存される
  3. strtypeオブジェクトを破棄するときにメモリが開放される
  4. s1にs2を代入すると、s2はs1と同じメモリを指すようになる
  5. そのため、s1オブジェクトを2度開放しようとする
  6. s2のpがメモリを示したポインタは開放されない これらの理由でコアダンプとなる。

そのため、オブジェクトを代入するときは注意が必要。




引用・参考はこちら

f:id:AtsuyaKoike:20190524100759j:plain:w200
独習C++ 第4版 https://www.amazon.co.jp/dp/4798119768