ためすう

_GLIBCXX_DEBUG を使ってみる (C++)

2020-04-18

確認環境

$ g++ --version
g++ (Homebrew GCC 9.2.0) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

調査

_GLIBCXX_DEBUG あり

test.cpp

#define _GLIBCXX_DEBUG

#include <bits/stdc++.h>
using namespace std;

int main() {
    vector<int> a(5);

    cout << "---1---" << endl;
    a[1] = 20;
    cout << a[1] << endl;
    cout << "---2---" << endl;
    a[10000000] = 99;
}

出力結果

---1---
20
---2---
/usr/local/Cellar/gcc/9.2.0/include/c++/9.2.0/debug/vector:427:
In function:
    std::__debug::vector<_Tp, _Allocator>::reference
    std::__debug::vector<_Tp,
    _Allocator>::operator[](std::__debug::vector<_Tp,
    _Allocator>::size_type) [with _Tp = int; _Allocator =
    std::allocator<int>; std::__debug::vector<_Tp, _Allocator>::reference =
    int&; std::__debug::vector<_Tp, _Allocator>::size_type = long unsigned
    int]

Error: attempt to subscript container with out-of-bounds index 10000000, but
container only holds 5 elements.

Objects involved in the operation:
    sequence "this" @ 0x0x7ffeebcfa610 {
      type = std::__debug::vector<int, std::allocator<int> >;
    }
Abort trap: 6

_GLIBCXX_DEBUG なし

test.cpp

#include <bits/stdc++.h>
using namespace std;

int main() {
    vector<int> a(5);

    cout << "---1---" << endl;
    a[1] = 20;
    cout << a[1] << endl;
    cout << "---2---" << endl;
    a[10000000] = 99;
}

出力結果

---1---
20
---2---
Segmentation fault: 11

_GLIBCXX_DEBUG ありだと、エラーの原因も記載されています。

参考

外部ファイルを読み込む (C++)

2020-04-12

確認環境

$ g++ --version
g++ (Homebrew GCC 9.2.0) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

調査

sample.txt

aaa
bbb
222
ccc

test.cpp

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define sz(x) int(x.size())
using namespace std;
typedef long long ll;
typedef pair<int, int> P;

const ll INF = 1LL << 60;

int main() {
    ifstream ifs("sample.txt");
    if (!ifs) {
        cout << "Miss" << endl;
    } else {
        // getを使って読み込むパターン
        // char c;
        // while (ifs.get(c)) {
        //     cout << c;
        // }

        // getline を使って読み込むパターン
        char s[100];
        while (ifs.getline(s, 100)) {
            cout << s << endl;
        }
    }
}

出力結果

aaa
bbb
222
ccc

参考

std::count を使ってみる (C++)

2020-04-05

確認環境

$ g++ --version
g++ (Homebrew GCC 9.2.0) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

調査

test.cpp

#include <bits/stdc++.h>
using namespace std;

int main() {
    vector<int> v = {3, 4, 3, 1, 2, 3};

    cout << "idx: 0 ~ 2 の範囲で 3 の数" << endl;
    cout << count(v.begin() + 0, v.begin() + 3, 3) << endl;

    cout << "idx: 0 ~ 1 の範囲で 3 の数" << endl;
    cout << count(v.begin() + 0, v.begin() + 2, 3) << endl;

    cout << "idx: 0 ~ 5 の範囲で 3 の数" << endl;
    cout << count(v.begin() + 0, v.begin() + 6, 3) << endl;
    cout << count(v.begin() + 0, v.end(), 3) << endl;

    cout << "idx: 2 ~ 5 の範囲で 3 の数" << endl;
    cout << count(v.begin() + 2, v.begin() + 6, 3) << endl;
}

出力結果

idx: 0 ~ 2 の範囲で 3 の数
2
idx: 0 ~ 1 の範囲で 3 の数
1
idx: 0 ~ 5 の範囲で 3 の数
3
3
idx: 2 ~ 5 の範囲で 3 の数
2

参考

<random> ライブラリを使ってみる (C++)

2020-04-05

確認環境

$ g++ --version
g++ (Homebrew GCC 9.2.0) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

調査

test.cpp

#include <bits/stdc++.h>
using namespace std;

int main() {
    std::random_device rng;
    for (int i = 0; i < 5; i++) {
        cout << rng() << endl;
    }
    cout << "---" << endl;
    std::mt19937 engine(rng());
    std::uniform_real_distribution<> dist1(-1.0, 1.0);
    for (int i = 0; i < 5; i++) {
        cout << dist1(engine) << endl;
    }

    cout << "-- 1 ~ 10 の整数を等確率で出力する --" << endl;
    std::random_device rng2;
    std::mt19937 engine2(rng2());
    std::uniform_int_distribution<> dist2(1, 10);
    for (int i = 0; i < 5; i++) {
        cout << dist2(engine2) << endl;
    }
}

出力結果

28733216
299212032
131005940
463750635
2721402783
---
-0.179933
-0.992599
-0.705688
-0.27019
-0.209114
-- int -
5
9
10
1
7

参考

swap を使ってみる (C++)

2020-04-04

確認環境

$ g++ --version
g++ (Homebrew GCC 9.2.0) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

調査

swap は、

2つの値を入れ替える。

使ってみます。

test.cpp

#include <bits/stdc++.h>
// #define NDEBUG
#include <cassert>
using namespace std;

int main() {
    int x = 100, y = 777;
    cout << "case1" << endl;
    printf("x: %d y: %d\n", x, y);

    cout << "case2" << endl;
    swap(x, y);
    printf("x: %d y: %d\n", x, y);

    cout << "end" << endl;
}

出力結果

case1
x: 100 y: 777
case2
x: 777 y: 100
end

参考

assert を使ってみる (C++)

2020-04-04

確認環境

$ g++ --version
g++ (Homebrew GCC 9.2.0) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

調査

assert は、

式が真であることを表明する。

使ってみます。

test.cpp

#include <bits/stdc++.h>
#include <cassert>
using namespace std;

int main() {
    cout << "case1" << endl;
    assert(10 > 5);

    cout << "case2" << endl;
    assert(10 < 5);

    cout << "end" << endl;
}

出力結果

case1
case2
Assertion failed: (10 < 5), function main, file assert.cpp, line 10.
Abort trap: 6

10 < 5 が偽であるため、failed になりました。

参考

読み取り専用ユーザーを作成する (MySQL)

2020-03-29

やったこと

MySQL で読み取りだけ実行可能なユーザーを作成します。

確認環境

$ mysql --version
mysql  Ver 14.14 Distrib 5.6.25, for Linux (x86_64) using  EditLine wrapper

調査

ユーザーを検索します。

mysql> SELECT user, host FROM mysql.user;
+------+-----------------------+
| user | host                  |
+------+-----------------------+
| root | 127.0.0.1             |
| root | ::1                   |
| root | localhost             |
| root | localhost.localdomain |
+------+-----------------------+
4 rows in set (0.00 sec)

SELECT 権限を持つユーザーを作成します。

mysql> GRANT SELECT ON test.* TO read1@localhost IDENTIFIED BY 'hogehoge';
Query OK, 0 rows affected (0.00 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

read1 ユーザーが作成されていることを確認します。

mysql> SELECT user, host FROM mysql.user;
+-------+-----------------------+
| user  | host                  |
+-------+-----------------------+
| root  | 127.0.0.1             |
| root  | ::1                   |
| read1 | localhost             |
| root  | localhost             |
| root  | localhost.localdomain |
+-------+-----------------------+
5 rows in set (0.00 sec)

ここで、read1 ユーザーで MySQL に再接続します。

$ mysql -u read1 -p test

SELECT は実行できます。

mysql> select * from test_table;
+----+------+------+------+
| id | col1 | col2 | col3 |
+----+------+------+------+
|  1 | 2    | 3    | 4    |
|  2 | 2    | 3    | 4    |
+----+------+------+------+
2 rows in set (0.00 sec)

権限がないので INSERT はエラーになりました。

mysql> insert into test_table values (3, 2, 3, 4);
ERROR 1142 (42000): INSERT command denied to user 'read1'@'localhost' for table 'test_table'

ユーザー削除 (root ユーザーで実行)

mysql> DROP USER 'read1'@'localhost';
Query OK, 0 rows affected (0.00 sec)

参考

emplace_back を使ってみる (C++)

2020-03-29

確認環境

$ g++ --version
g++ (Homebrew GCC 9.2.0) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

調査

test.cpp

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, string> P;
typedef tuple<ll, ll, string> T;

int main() {

    vector<P> v;
    v.push_back(P(1, "aaa"));
    v.emplace_back(2, "bbb");
    cout << "pair" << endl;
    for (int i = 0; i < v.size(); i++) {
        cout << v[i].first << " " << v[i].second << endl;
    }

    vector<T> v2;
    v2.push_back(T(1, 100, "mmm"));
    v2.emplace_back(2, 200, "nnn");

    cout << "tupple" << endl;
    for (int i = 0; i < v2.size(); i++) {
        cout << get<0>(v2[i]) << " " << get<1>(v2[i]) << " " << get<2>(v2[i]) << endl;
    }
}

出力結果

pair
1 aaa
2 bbb
tupple
1 100 mmm
2 200 nnn

参考

octopus を使ってみる (Rails)

2020-03-28

やったこと

octopus をインストールして使ってみます。

確認環境

$ ruby --version
ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin17]

$ rails --version
Rails 5.2.3

$ sqlite3 --version
3.20.1 2017-08-24 16:21:36 8d3a7ea6c5690d6b7c3767558f4f01b511c55463e3f9e64506801fe9b74dce34

調査

今回 octopus という gem を使います。

octopus は下記機能を提供しています。

  • Sharding (with multiple shards, and grouped shards).
  • Replication (Master/slave support, with multiple slaves).
  • Moving data between shards with migrations.
  • Tools to manage database configurations. (soon)

Replication について動きを確かめてみます。

インストール

Gemfile

gem 'ar-octopus'

config

config/shards.yml

octopus:
  replicated: true
  environments:
    - development
  development:
    shard1:
      adapter: sqlite3
      database: db/development.slave1.sqlite3
    shard2:
      adapter: sqlite3
      database: db/development.slave2.sqlite3

アクセスしてみる

別々にアクセスしていることを確認するため、 使用するテーブルの最終行にデータを入れました。

  • development.slave1.sqlite3
  • development.slave2.sqlite3
$ rails c
Running via Spring preloader in process 74218
Loading development environment (Rails 5.2.4.1)
irb(main):001:0> Book.last
[Shard: shard2]  Book Load (0.4ms)  SELECT  "books".* FROM "books" ORDER BY "books"."id" DESC LIMIT ?  [["LIMIT", 1]]
=> #<Book id: 4, title: "222", status: nil, created_at: "2020-03-15 07:58:57", updated_at: "2020-03-15 07:58:57">
irb(main):002:0> Book.last
[Shard: shard1]  Book Load (0.1ms)  SELECT  "books".* FROM "books" ORDER BY "books"."id" DESC LIMIT ?  [["LIMIT", 1]]
=> #<Book id: 5, title: "123", status: 1, created_at: "2020-03-28 00:00:00", updated_at: "2020-03-28 00:00:00">

shard1、shard2 によって、異なるデータを取得していることが分かります。

最後に

Octopus will enter into maintainance mode once Rails 6 is released

Rails6 がリリースされているので、メンテナンスモードになっているようです。

sqrt、sqrtf、sqrtl を使ってみる (C++)

2020-03-28

確認環境

$ g++ --version
g++ (Homebrew GCC 9.2.0) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

調査

3の平方根を計算してみます。

今回は下記の関数を使ってみます。

  • sqrtf (float)
  • sqrt (double)
  • sqrtl (long double)

test.cpp

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

int main() {
    printf("%.80f\n", sqrtf((float)3));
    printf("%.80f\n", sqrt(3));
    printf("%.80Lf\n", sqrtl((long double)3));
}

出力結果

1.73205077648162841796875000000000000000000000000000000000000000000000000000000000
1.73205080756887719317660412343684583902359008789062500000000000000000000000000000
1.73205080756887729357372529559455642811371944844722747802734375000000000000000000

参考