C++のoperator new/operator deleteについて

April 25,2017 12:03 AM
Category:[C/C++]
Tag:[C/C++]
Permalink

C++のoperator new/operator deleteについて紹介します。

1.サンプル

まず最初にサンプルをご覧ください。

#include <cstdio>
#include <cstdlib>
 
class Test {
 
private:
 
    int number;
 
public:
 
    Test(int num) {
        number = num;
        std::printf("constructor: %d\n", number);
    }
 
    ~Test() {
        std::printf("destructor\n");
    }
 
    void* operator new(std::size_t sz) {
        std::printf("operator new: %zu\n",sz);
        return std::malloc(sz);
    }
 
    void operator delete(void* ptr) {
        std::printf("operator delete: %p\n", ptr);
        std::free(ptr);
    }
};
 
int main() {
     Test* test = new Test(100);
     delete test;
}

このサンプルを元にoperator new/operator deleteについて紹介します。

2.operator new/operator deleteとは

operator new/operator deleteは、コンストラクタ起動時、特定のエリアからメモリを確保(または解放)するための仕組みです。

通常のコンストラクタは、

  • メモリの割当
  • オブジェクトの構築

という2つの動作を行いますが、operator newはメモリの割り当てを実行します。

サンプルでは下記の部分になります。

void* operator new(std::size_t sz) {
    std::printf("operator new: %zu\n",sz);
    return std::malloc(sz);
}

引数の"size_t"はC++の仕様で決められたもので、オブジェクトのサイズになります。

ユーザーがコンストラクタ起動時にパラメータにサイズを指定する必要はありません(おそらくコンパイラ時にオブジェクトのサイズが分かる)。

また、戻り値の型は"void *"です。

operator deleteは下記の部分です。

void operator delete(void* ptr) {
    std::printf("operator delete: %p\n", ptr);
    std::free(ptr);
}

引数は確保したアドレスになります。こちらもデストラクタ起動時のパラメータに指定する必要はありません。

3.newとoperator newの違い

operator newはnewのオーバーロード(引数や戻り値が異なるが名称が同一のメソッドを複数定義すること)ですが、operator newとnewが存在する場合、順番に起動されることから、個人的には通常のオーバーロードとは動作が異なる気がします。

具体的には、ユーザープログラムがコンストラクタを実行すると、先にoperator newが起動されてメモリ確保等を行い、その後通常のコンストラクタが起動するようになっています。

デストラクタの動作はその逆で、先に通常のデストラクタが起動され、operator deleteが動作してメモリ解放を行います。

サンプルで説明すると、mainに記述した、

Test* test = new Test(100);

が実行されることで、最初に、

void* operator new(std::size_t sz) { ... }

が起動してmallocでメモリを確保し、その後

Test(int num) { ... }

が起動します。

サンプルの実行結果は下記のようになります。

operator new: 4
constructor: 100
address: 0x12a9010
destructor
operator delete

「4」というのは、クラスで定義した変数

int number;

のサイズになります。

4.参考サイト

参考サイトは下記です。ありがとうございました。

Comments [0] | Trackbacks [0]

Jenkinsのインストール(Windows版)

April 18,2017 12:55 AM
Category:[Jenkins]
Tag:[Jenkins]
Permalink

Jenkinsのインストール(Windows版)について紹介します。

jenkinsのページにアクセスして、「Download」をクリック。

「Long-Term Support」の下にある「Windows」をクリックすればダウンロードが開始します。

ダウンロードしたアーカイブを展開して、jenkins.msiを実行すればインストールウィザードが開始します。

(クリックで拡大、以下同様)

インストール終了後、"http://localhost:8080"にアクセスして下記のページを開きます(または自動的に開きます)。

「Administrator password」に、C:\Program Files\Jenkins\secrets\initialAdminPasswordに記載されたパスワードをペーストして「Continue」をクリック。

通常はここで「Install suggested plugins」という画面になりますが、Proxyサーバが設置されていて正常に外部にアクセスできない環境では「Offline」と表示されるようです。

ということで、「Configure Proxy」をクリック。

プロキシサーバのIPアドレス・ポートなどを入力して、「Save and Continue」をクリック。

接続が正常に行えるようになれば次の画面が表示されるので、「Install suggested plugins」をクリック。正常に接続できない場合、画面をリロードすれば最初の画面に戻れます。

画面が切り替わり、プラグインのインストールが開始します(完了まで数分かかります)。

最後にJenkinsを利用するユーザーを作成し、「Save and Finish」をクリック。

これでインストール完了です。

「Start using Jenkins」をクリックすると次のような画面が表示されます。

Comments [0] | Trackbacks [0]

AIXでカーネルbitモードを判定する方法

April 14,2017 12:03 AM
Category:[Linux]
Tag:[AIX]
Permalink

AIXでカーネルbitモードを判定する方法を紹介します。

AIXはIBMのUNIXオペレーティングシステムのブランド名です。

1.問題点

Linuxでカーネルbitモードを判定するには、"uname -a"を利用します。

% uname -a
Linux file.hoge.local 3.10.0-327.el7.x86_64 #1 SMP Thu Nov 19 22:10:57 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux

i686やi386と表示された場合は32bitモード、X86_64やamd64と表示された場合は64bitモードになります。

がAIXで"uname -a"を入力しても期待する出力になりません。

% uname -a
AIX hoge 2 7 00F73ACC5C00

ということで、AIXでカーネルbitモードを判定する方法を紹介します。

2.カーネルbitモードを判定する

カーネルbitモードを判定するには、rootユーザーで"bootinfo -K"を利用します。

# bootinfo -K
64

"32"が32bitモード、"64"が64bitモードを指します。

Comments [0] | Trackbacks [0]

C/C++で「`shm_open' に対する定義されていない参照です」というエラーになった場合の対処

April 13,2017 12:55 AM
Category:[C/C++]
Tag:[C/C++]
Permalink

C/C++で「`shm_open' に対する定義されていない参照です」というエラーになった場合の対処方法について紹介します。

1.問題点

shm_openとshm_unlinkを使用する下記のサンプルコードを書きました。

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
 
#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)
 
int main() {
    int* ptr;
    int fd;
    int ret;
 
    fd = shm_open("/test",  O_CREAT | O_RDWR, FILE_MODE);
    if(fd == -1) {
        exit;
    }
 
    ret = ftruncate(fd, sizeof(int));
    ptr = mmap (0, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(ptr == MAP_FAILED) {
        exit;
    }
    printf("ptr:%p\n", ptr);
 
    if (ret = shm_unlink("/test")) {
        fprintf (stderr, "shm_unlink(shm_struct) failed\n");
    }
    return 1;
}

このコードをコンパイルすると、下記のように「shm_openおよびshm_unlinkの実装が定義されていない」というエラーが発生します。

% gcc shm.c
/tmp/cctpXmiN.o: 関数 `main' 内:
shm.c:(.text+0x18): `shm_open' に対する定義されていない参照です
shm.c:(.text+0x7b): `shm_unlink' に対する定義されていない参照です
collect2: エラー: ld はステータス 1 で終了しました

ということで、「`shm_open' に対する定義されていない参照です」というエラーになった場合の対処方法について紹介します。

2.対処方法

調べたところ、コンパイルオプションに"-lrt"を付与することで解消します。

% gcc -lrt shm.c

"-l"はリンケージ時のライブラリ(ここではrt)を指定するためのオプションです。

Comments [0] | Trackbacks [0]

iptablesでhttp・https接続を許可する方法

April 11,2017 12:03 AM
Category:[Linux]
Tag:[]
Permalink

iptablesでhttp・https接続を許可する方法を紹介します。

1.問題点

使い回しのLinuxサーバにApacheをインストールしましたが、外部からアクセスするとタイムアウトが発生します。

Linux内部からのアクセスはOKなので、iptablesで接続が許可されていない可能性があります。

ということで、iptablesでhttp・https接続を許可する方法を紹介します。

2.iptablesでhttp・https接続を許可する

iptablesの設定状況を確認するには"-L"オプションを指定します。

情報が設定されていれば次のような内容が表示されます。

# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere
ACCEPT     all  --  anywhere             anywhere
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ms-wbt-server
ACCEPT     udp  --  anywhere             anywhere            state NEW udp dpt:ntp
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited
 
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited
 
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

ちなみに、iptablesに何も設定していない状態であれば次のように表示されます。

# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination
 
Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
 
Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

また、"--line-numbers"を設定すれば、一番左に"num"が表示されます。

# iptables -L --line-numbers
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
2    ACCEPT     icmp --  anywhere             anywhere
3    ACCEPT     all  --  anywhere             anywhere
4    ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh
5    ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ms-wbt-server
6    ACCEPT     udp  --  anywhere             anywhere            state NEW udp dpt:ntp
7    REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited
 
Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination
1    REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited
 
Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination

iptablesのルールは上から適用されるようで、http接続を許可するための新しいルールは7番目のREJECTよりも上に設定する必要があります。

今回はすでにiptablesが設定された状態のため、5と6の間に新しいルール(http接続許可)を、下記のコマンドで追加します。

# iptables -I INPUT 6 -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT

以下、パラメータの説明です。

"-I INPUT 6"でルールを追加する位置を指定します。「6」を指定したので5の直後にルールが追加され、既存の「6」以降のルールはひとつずつ後ろにずれます。

"--state NEW"は接続開始要求パケット(SYNパケット)のみ許可することを意味します。

上記のstateマッチを利用するため、"-m state"もペアで設定し、拡張モジュールを指定します。

"-p tcp"はTCPプロトコルを指定します。"-m tcp"もペアで設定し、拡張モジュールを指定します(/etc/sysconfig/iptablesでは暗黙的に設定されているもので、コマンドラインでは設定不要かも)。

"--dport 80"でポート番号80(http)を指定します。httpsの場合は80の部分が443になります。

"-j ACCEPT"で許可を指定します。

設定後の表示は次のようになります(赤色が追加された内容)。

# iptables -L --line-numbers
Chain INPUT (policy ACCEPT)
num  target     prot opt source               destination
1    ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED
2    ACCEPT     icmp --  anywhere             anywhere
3    ACCEPT     all  --  anywhere             anywhere
4    ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ssh
5    ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:ms-wbt-server
6    ACCEPT     tcp  --  anywhere             anywhere            state NEW tcp dpt:http
7    ACCEPT     udp  --  anywhere             anywhere            state NEW udp dpt:ntp
8    REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited
 
Chain FORWARD (policy ACCEPT)
num  target     prot opt source               destination
1    REJECT     all  --  anywhere             anywhere            reject-with icmp-host-prohibited
 
Chain OUTPUT (policy ACCEPT)
num  target     prot opt source               destination

設定変更後、iptablesを再起動しなくてもhttp接続OKになりました。

3.iptablesの設定を削除する

もしiptablesの設定を削除したいのであれば、

# iptables -F

を実行します。

4.参考サイト

参考サイトは下記です。ありがとうございました。

Comments [0] | Trackbacks [0]

楽天トラベルで領収書を取得する方法

April 7,2017 12:03 AM
Category:[その他]
Tag:[Rakuten]
Permalink

楽天トラベルで領収書を取得する方法を紹介します。

1.はじめに

会社の出張で楽天トラベルを使ってホテルを予約しました。

出張後、会社にホテルの領収書提示が必要だったのですが、フロントでもらうのをうっかり忘れてしまいました。

なんとかならないか調べてみたところ、楽天トラベルで予約した場合、オンラインで領収書を発行してもらえることが分かりました。

ということで、楽天トラベルで領収書を取得する方法を紹介します。

2.領収書を取得する

領収書を取得するには、楽天トラベルのページからログイン。

楽天トラベルのページ

「予約の確認・キャンセル」をクリック。

予約の確認・キャンセル

「キャンセル済・過去の予約」をクリック。

予約の確認・キャンセル

該当予約の「領収書発行」をクリック(画面は2回目なので「再発行」になっています)。

(クリックで拡大)
領収書発行

宛名を適切な内容に変更して「宛名確認へ」をクリック。

宛名確認へ

宿泊所の住所をいれたい場合はチェックボックスをチェックして「領収書発行」をクリック。

領収書発行

このあと領収書画面が表示されるので、印刷すればOKです。

領収書は「発行」と「再発行」で2回まで表示できるようです。

Comments [0] | Trackbacks [0]

gcc/g++でリンカスクリプトを調べる方法

April 5,2017 12:03 AM
Category:[C/C++]
Tag:[C/C++]
Permalink

gcc/g++でリンカスクリプトを調べる方法を紹介します。

1.問題点

下記のサンプルコードを作りました。

sample.cpp

#include <stdio.h>
 
void hello_world2(void) {
    printf( "Hello World2!\n" );                                                                                                                              }
 
void hello_world1(void) {
    printf( "Hello World1!\n" );
    hello_world2();
}
 
int main(void) {
    hello_world1();
    return 0;
}

このコードをビルドするときに実行されるリンカスクリプト(プログラムやデータをどのアドレスに配置するかを決めるためのスクリプト)を調べたいのですが、調べる方法が分かりません。

ということで、リンカスクリプトを調べる方法を紹介します。

2.リンカスクリプトを調べる

リンカスクリプトを調べるには、ビルド時にオプション"-Wl,--verbose"を付与します。

% g++ -Wl,--verbose sample.cpp

"-Wl,option"でオプションoptionをリンカに渡します。

optionがカンマを含む場合、複数のオプションとして分割されます。

リンカオプション"--verbose"は、ld のバージョン番号を表示し、サポートされているエミュレーションをリストします。

コマンド実行結果が下記で、"========"で括られた部分がリンカスクリプトになります。

% g++ -Wl,--verbose sample.cpp
GNU ld version 2.23.52.0.1-55.el7 20130226
  サポートされているエミュレーション:
   elf_x86_64
   elf32_x86_64
   elf_i386
   i386linux
   elf_l1om
   elf_k1om
内部リンカスクリプトを使用しています:
==================================================
/* Script for -z combreloc: combine and sort reloc sections */
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64",
              "elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)
SEARCH_DIR("/usr/x86_64-redhat-linux/lib64"); SEARCH_DIR("/usr/local/lib64"); SEARCH_DIR("/lib64"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/x86_64-redhat-linux/lib"); SEARCH_DIR("/usr/lib64"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib");
SECTIONS
{
  /* Read-only sections, merged into text segment: */
  PROVIDE (__executable_start = SEGMENT_START("text-segment", 0x400000)); . = SEGMENT_START("text-segment", 0x400000) + SIZEOF_HEADERS;
  .interp         : { *(.interp) }
  .note.gnu.build-id : { *(.note.gnu.build-id) }
  .hash           : { *(.hash) }
  .gnu.hash       : { *(.gnu.hash) }
  .dynsym         : { *(.dynsym) }
  .dynstr         : { *(.dynstr) }
  .gnu.version    : { *(.gnu.version) }
  .gnu.version_d  : { *(.gnu.version_d) }
  .gnu.version_r  : { *(.gnu.version_r) }
  .rela.dyn       :
    {
      *(.rela.init)
      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)
      *(.rela.fini)
      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)
      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)
      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)
      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)
      *(.rela.ctors)
      *(.rela.dtors)
      *(.rela.got)
      *(.rela.sharable_data .rela.sharable_data.* .rela.gnu.linkonce.shrd.*)
      *(.rela.sharable_bss .rela.sharable_bss.* .rela.gnu.linkonce.shrb.*)
      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
      *(.rela.ldata .rela.ldata.* .rela.gnu.linkonce.l.*)
      *(.rela.lbss .rela.lbss.* .rela.gnu.linkonce.lb.*)
      *(.rela.lrodata .rela.lrodata.* .rela.gnu.linkonce.lr.*)
      *(.rela.ifunc)
    }
  .rela.plt       :
    {
      *(.rela.plt)
      PROVIDE_HIDDEN (__rela_iplt_start = .);
      *(.rela.iplt)
      PROVIDE_HIDDEN (__rela_iplt_end = .);
    }
  .init           :
  {
    KEEP (*(SORT_NONE(.init)))
  }
  .plt            : { *(.plt) *(.iplt) }
  .text           :
  {
    *(.text.unlikely .text.*_unlikely)
    *(.text.exit .text.exit.*)
    *(.text.startup .text.startup.*)
    *(.text.hot .text.hot.*)
    *(.text .stub .text.* .gnu.linkonce.t.*)
    /* .gnu.warning sections are handled specially by elf32.em.  */
    *(.gnu.warning)
  }
  .fini           :
  {
    KEEP (*(SORT_NONE(.fini)))
  }
  PROVIDE (__etext = .);
  PROVIDE (_etext = .);
  PROVIDE (etext = .);
  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
  .rodata1        : { *(.rodata1) }
  .eh_frame_hdr : { *(.eh_frame_hdr) }
  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }
  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table
  .gcc_except_table.*) }
  /* These sections are generated by the Sun/Oracle C++ compiler.  */
  .exception_ranges   : ONLY_IF_RO { *(.exception_ranges
  .exception_ranges*) }
  /* Adjust the address for the data segment.  We want to adjust up to
     the same address within the page on the next page up.  */
  . = ALIGN (CONSTANT (MAXPAGESIZE)) - ((CONSTANT (MAXPAGESIZE) - .) & (CONSTANT (MAXPAGESIZE) - 1)); . = DATA_SEGMENT_ALIGN (CONSTANT (MAXPAGESIZE), CONSTANT (COMMONPAGESIZE));
  /* Exception handling  */
  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }
  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }
  .exception_ranges   : ONLY_IF_RW { *(.exception_ranges .exception_ranges*) }
  /* Thread Local Storage sections  */
  .tdata          : { *(.tdata .tdata.* .gnu.linkonce.td.*) }
  .tbss           : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }
  .preinit_array     :
  {
    PROVIDE_HIDDEN (__preinit_array_start = .);
    KEEP (*(.preinit_array))
    PROVIDE_HIDDEN (__preinit_array_end = .);
  }
  .init_array     :
  {
    PROVIDE_HIDDEN (__init_array_start = .);
    KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*)))
    KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors))
    PROVIDE_HIDDEN (__init_array_end = .);
  }
  .fini_array     :
  {
    PROVIDE_HIDDEN (__fini_array_start = .);
    KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*)))
    KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors))
    PROVIDE_HIDDEN (__fini_array_end = .);
  }
  .ctors          :
  {
    /* gcc uses crtbegin.o to find the start of
       the constructors, so we make sure it is
       first.  Because this is a wildcard, it
       doesn't matter if the user does not
       actually link against crtbegin.o; the
       linker won't look for a file to match a
       wildcard.  The wildcard also means that it
       doesn't matter which directory crtbegin.o
       is in.  */
    KEEP (*crtbegin.o(.ctors))
    KEEP (*crtbegin?.o(.ctors))
    /* We don't want to include the .ctor section from
       the crtend.o file until after the sorted ctors.
       The .ctor section from the crtend file contains the
       end of ctors marker and it must be last */
    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))
    KEEP (*(SORT(.ctors.*)))
    KEEP (*(.ctors))
  }
  .dtors          :
  {
    KEEP (*crtbegin.o(.dtors))
    KEEP (*crtbegin?.o(.dtors))
    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))
    KEEP (*(SORT(.dtors.*)))
    KEEP (*(.dtors))
  }
  .jcr            : { KEEP (*(.jcr)) }
  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro .data.rel.ro.* .gnu.linkonce.d.rel.ro.*) }
  .dynamic        : { *(.dynamic) }
  .got            : { *(.got) *(.igot) }
  . = DATA_SEGMENT_RELRO_END (SIZEOF (.got.plt) >= 24 ? 24 : 0, .);
  .got.plt        : { *(.got.plt)  *(.igot.plt) }
  .data           :
  {
    *(.data .data.* .gnu.linkonce.d.*)
    SORT(CONSTRUCTORS)
  }
  .data1          : { *(.data1) }
  /* Sharable data sections.  */
  .sharable_data   : ALIGN(CONSTANT (MAXPAGESIZE))
  {
    PROVIDE_HIDDEN (__sharable_data_start = .);
    *(.sharable_data .sharable_data.* .gnu.linkonce.shrd.*)
    /* Align here to ensure that the sharable data section ends at the
       page boundary.  */
    . = ALIGN(. != 0 ? CONSTANT (MAXPAGESIZE) : 1);
    PROVIDE_HIDDEN (__sharable_data_end = .);
  }
  _edata = .; PROVIDE (edata = .);
  . = .;
  __bss_start = .;
  .bss            :
  {
   *(.dynbss)
   *(.bss .bss.* .gnu.linkonce.b.*)
   *(COMMON)
   /* Align here to ensure that the .bss section occupies space up to
      _end.  Align after .bss to ensure correct alignment even if the
      .bss section disappears because there are no input sections.
      FIXME: Why do we need it? When there is no .bss section, we don't
      pad the .data section.  */
   . = ALIGN(. != 0 ? 64 / 8 : 1);
  }
  /* Sharable bss sections  */
  .sharable_bss   : ALIGN(CONSTANT (MAXPAGESIZE))
  {
    PROVIDE_HIDDEN (__sharable_bss_start = .);
    *(.dynsharablebss)
    *(.sharable_bss .sharable_bss.* .gnu.linkonce.shrb.*)
    *(SHARABLE_COMMON)
    /* Align here to ensure that the sharable bss section ends at the
       page boundary.  */
    . = ALIGN(. != 0 ? CONSTANT (MAXPAGESIZE) : 1);
    PROVIDE_HIDDEN (__sharable_bss_end = .);
  }
  .lbss   :
  {
    *(.dynlbss)
    *(.lbss .lbss.* .gnu.linkonce.lb.*)
    *(LARGE_COMMON)
  }
  . = ALIGN(64 / 8);
  . = SEGMENT_START("ldata-segment", .);
  .lrodata   ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
  {
    *(.lrodata .lrodata.* .gnu.linkonce.lr.*)
  }
  .ldata   ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1)) :
  {
    *(.ldata .ldata.* .gnu.linkonce.l.*)
    . = ALIGN(. != 0 ? 64 / 8 : 1);
  }
  . = ALIGN(64 / 8);
  _end = .; PROVIDE (end = .);
  . = DATA_SEGMENT_END (.);
  /* Stabs debugging sections.  */
  .stab          0 : { *(.stab) }
  .stabstr       0 : { *(.stabstr) }
  .stab.excl     0 : { *(.stab.excl) }
  .stab.exclstr  0 : { *(.stab.exclstr) }
  .stab.index    0 : { *(.stab.index) }
  .stab.indexstr 0 : { *(.stab.indexstr) }
  .comment       0 : { *(.comment) }
  /* DWARF debug sections.
     Symbols in the DWARF debugging sections are relative to the beginning
     of the section so we begin them at 0.  */
  /* DWARF 1 */
  .debug          0 : { *(.debug) }
  .line           0 : { *(.line) }
  /* GNU DWARF 1 extensions */
  .debug_srcinfo  0 : { *(.debug_srcinfo) }
  .debug_sfnames  0 : { *(.debug_sfnames) }
  /* DWARF 1.1 and DWARF 2 */
  .debug_aranges  0 : { *(.debug_aranges) }
  .debug_pubnames 0 : { *(.debug_pubnames) }
  /* DWARF 2 */
  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }
  .debug_abbrev   0 : { *(.debug_abbrev) }
  .debug_line     0 : { *(.debug_line) }
  .debug_frame    0 : { *(.debug_frame) }
  .debug_str      0 : { *(.debug_str) }
  .debug_loc      0 : { *(.debug_loc) }
  .debug_macinfo  0 : { *(.debug_macinfo) }
  /* SGI/MIPS DWARF 2 extensions */
  .debug_weaknames 0 : { *(.debug_weaknames) }
  .debug_funcnames 0 : { *(.debug_funcnames) }
  .debug_typenames 0 : { *(.debug_typenames) }
  .debug_varnames  0 : { *(.debug_varnames) }
  /* DWARF 3 */
  .debug_pubtypes 0 : { *(.debug_pubtypes) }
  .debug_ranges   0 : { *(.debug_ranges) }
  /* DWARF Extension.  */
  .debug_macro    0 : { *(.debug_macro) }
  .gnu.attributes 0 : { KEEP (*(.gnu.attributes)) }
  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.gnu_object_only) }
}
 
 
==================================================
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o を開くのに成功しました
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crt1.o
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o を開くのに成功しました
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crti.o
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o を開くのに成功しました
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtbegin.o
/tmp/cc3kRI4P.o を開くのに成功しました
/tmp/cc3kRI4P.o
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libstdc++.so を開くのに成功しました
-lstdc++ (/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libstdc++.so)
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libm.so を開くのに失敗しました
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libm.a を開くのに失敗しました
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libm.so を開くのに成功しました
-lm (/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libm.so)
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc_s.so を開くのに成功しました
-lgcc_s (/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc_s.so)
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc.so を開くのに失敗しました
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc.a を開くのに成功しました
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libc.so を開くのに失敗しました
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libc.a を開くのに失敗しました
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libc.so を開くのに成功しました
スクリプトファイル /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libc.so が開かれました
スクリプトファイル /usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/libc.so が開かれました
/lib64/libc.so.6 を開くのに成功しました
/lib64/libc.so.6
/usr/lib64/libc_nonshared.a を開くのに成功しました
(/usr/lib64/libc_nonshared.a)elf-init.oS
/lib64/ld-linux-x86-64.so.2 を開くのに成功しました
/lib64/ld-linux-x86-64.so.2
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc_s.so を開くのに成功しました
-lgcc_s (/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc_s.so)
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc.so を開くのに失敗しました
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/libgcc.a を開くのに成功しました
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o を開くのに成功しました
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/crtend.o
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crtn.o を開くのに成功しました
/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../lib64/crtn.o
ld-linux-x86-64.so.2 needed by /usr/lib/gcc/x86_64-redhat-linux/4.8.5/libstdc++.so
found ld-linux-x86-64.so.2 at /lib64/ld-linux-x86-64.so.2
Comments [0] | Trackbacks [0]

ExcelのCSVデータ取り込みで「このテキストファイルのデータは、1つのワークシートに入りきりません。」というエラーになる場合の対処

March 27,2017 12:03 AM
Category:[Excel]
Tag:[Excel, Office]
Permalink

ExcelのCSVデータ取り込みで「このテキストファイルのデータは、1つのワークシートに入りきりません。」というエラーになる場合の対処方法を紹介します。

「このテキストファイルのデータは、1つのワークシートに入りきりません。」

1.問題点

ExcelのCSVデータ取り込みで「このテキストファイルのデータは、1つのワークシートに入りきりません。」というエラーが発生しました。

データは下記に示す、5行程度の短いものです。

テスト1-1,テスト1-2,テスト1-3
テスト2-1,テスト2-2,テスト2-3
テスト3-1,テスト3-2,テスト3-3
テスト4-1,テスト4-2,テスト4-3
テスト5-1,テスト5-2,テスト5-3

CSVファイルの取り込み手順は下記のとおりです。

「データ」→「外部データの取り込み」→「テキストファイル」をクリックしてインポートしたいCSVファイルを選択。

テキストファイル

「テキストファイルウィザード - 1/3」画面にある、「元のファイル」から「65001 : Unicode (UTF-8)」を選択。

(クリックで拡大)
65001 : Unicode (UTF-8)

プレビューで正常に表示されていることを確認して「次へ」をクリック。

プレビュー

「カンマ」をチェックして「完了」をクリック。

開始セル(ここではA1)を指定して「OK」をクリック。

開始セル(ここではA1)を指定

ここでタイトルの「このテキストファイルのデータは、1つのワークシートに入りきりません。」というエラーに遭遇します。

(クリックで拡大)
「このテキストファイルのデータは、1つのワークシートに入りきりません。」

ちなみにこのダイアログを「OK」をクリックしてとじると、次のように最初の1行だけが取り込まれた状態になります。

最初の1行だけが取り込まれた状態

1つのワークシートに入りきらない量ではないので、対処方法が分かりません。

ということで、「このテキストファイルのデータは、1つのワークシートに入りきりません。」というエラーになる場合の対処方法を紹介します。

2.原因

このメッセージが表示される原因は、CSVファイルの改行コードがLFになっている場合に発生するようです。

エラーメッセージのあとに最初の1行しか取り込めていないのは、1行目の改行コード以降が正常に読み込めないためと思われます。

3.対処

テキストエディタでCSVファイルを開き、改行コードをCRLFに変換して保存します。

これで正常に取り込むことができます。

正常に取り込む

Comments [0] | Trackbacks [0]

ExcelでUTF-8のCSVデータを取り込む方法

March 24,2017 12:03 AM
Category:[Excel]
Tag:[Excel, Office]
Permalink

ExcelでUTF-8のCSVデータを取り込む方法を紹介します。

1.問題点

次のような文字コードがUTF-8のCSVファイルがあります。

テスト1-1,テスト1-2,テスト1-3
テスト2-1,テスト2-2,テスト2-3
テスト3-1,テスト3-2,テスト3-3
テスト4-1,テスト4-2,テスト4-3
テスト5-1,テスト5-2,テスト5-3

このファイルをダブルクリックしてExcelに取り込むと、文字化けします。

こういう場合、テキストエディタでCSVファイルを開き、文字コードをShift_JISに変換して一旦保存し直してから取り込むのですが、編集後もUTF-8のまま保存したいので、できればそのままの文字コードで開きたいです。

ということで、ExcelでUTF-8のCSVデータを取り込む方法を紹介します。

2.UTF-8のCSVデータを取り込む

UTF-8のCSVデータを取り込むには、「データ」→「外部データの取り込み」→「テキストファイル」をクリックしてインポートしたいCSVファイルを選択。

テキストファイル

「テキストファイルウィザード - 1/3」画面にある、「元のファイル」から「65001 : Unicode (UTF-8)」を選択。

(クリックで拡大、以下同様)
65001 : Unicode (UTF-8)

プレビューで正常に表示されていることを確認して「次へ」をクリック。

プレビュー

カンマ区切りなので「カンマ」をチェックして「完了」をクリック。

カンマ

開始セル(ここではA1)を指定して「OK」をクリック。

開始セル(ここではA1)を指定

これでCSVデータが正常に読み込まれます。

CSVデータ

3.BOMつきのUTF-8にする

BOMつきのUTF-8であれば、ダブルクリックでそのまま開けます。

BOMというのは、ファイルの先頭につけられたバイトオーダーマーク (byte order mark) のことで、UTF-8の場合「0xEF 0xBB 0xBF」という文字が付与されます。

ダブルクリックでExcelを開いたとき、ExcelはファイルのBOMをチェックして、「BOMがあればUTF-8」で開くという動作になっているようです。

UTF-8ファイルにBOMを付与するには、Windowsのメモ帳でCSVファイルで開き、そのまま保存すればOKです。

4.その他

UTF-8にはBOMあり・BOMなしの2種類がありますが、確認したところどちらのデータも正常に取り込めるようです。

ただし改行コードはCRLFになっている必要があります。

Comments [0] | Trackbacks [0]

IEで「前回のブラウズ セッションは予期せずに終了しました「セッションの復元」」が表示される場合の対処

March 23,2017 12:03 AM
Category:[IE]
Tag:[IE]
Permalink

IEで「前回のブラウズ セッションは予期せずに終了しました「セッションの復元」」が表示される場合の対処方法を紹介します。

1.問題点

IEを起動するたびに「前回のブラウズ セッションは予期せずに終了しました「セッションの復元」」が表示されます。

(クリックで拡大)
前回のブラウズ セッションは予期せずに終了しました「セッションの復元」

が、「セッションの復元」をクリックしても前回のセッションが復元されません。

復元はされなくてもいいのですが、このメッセージが表示されないようにする方法が分かりません。

ということで、IEで「前回のブラウズ セッションは予期せずに終了しました「セッションの復元」」が表示される場合の対処方法を紹介します。

2.メッセージが表示されないようにする

メッセージが表示されないようにするには、「ツール」アイコン→「インターネットオプション」をクリック。

「詳細設定」タブをクリック。

「自動クラッシュ回復機能を有効にする」のチェックを外して「OK」をクリック。

これで「セッションの復元」のメッセージが表示されないようになります。

Comments [0] | Trackbacks [0]

Linuxで「Too many open files」というエラーになる場合の対処

March 16,2017 12:03 AM
Category:[Linux]
Tag:[Linux]
Permalink

Linuxで「Too many open files」というエラーになる場合の対処について紹介します。

ここではnkfコマンドを例にしていますが、他のコマンドでも適用可能です。

1.問題点

nkfで1000ファイルほどの文字コードをUTF-8に変更しようとしたところ、「Too many open files」というエラーに遭遇しました。

% nkf -w --overwrite *
hoge.txt.nkftmp6vpeDo: Too many open files

エラーの後、該当ファイル以降の文字コードが変換されていませんでした。

2.原因

エラーになる原因は、nkfコマンド実行時、プロセスが開けるファイルディスクリプタの上限数を超えてしまうためのようです。

3.対処

nkfではファイルディスクリプタの上限数を設定できないため、findコマンド、xargsコマンドと組み合わせて実行します。

% find . -type f | xargs -n 256 nkf -w --overwrite

xargsの-nオプションで、nkfコマンドに一度に渡す引数の数を制御できます。

ここでは256を設定していますが、256を超えたら繰り返されます。

Comments [0] | Trackbacks [0]

C/C++でSegmentation faultが発生した場所を特定する方法

March 14,2017 12:03 AM
Category:[C/C++]
Tag:[C/C++]
Permalink

C/C++でSegmentation faultが発生した場所を特定する方法を紹介します。

1.問題点

下記のサンプルプログラム(test.cc)を作りました。

test.cc

#include <stdio.h>
 
void test() {
    char *p;
    p = 0;
    printf("%c\n", *p);
}
 
int main() {
    test();
    return 1;
}

コンパイルします。

% g++ -g test.cc

このプログラムを実行するとSegmentation faultが発生します。

% ./a.out
Segmentation fault (コアダンプ)

が、どこでエラーが発生しているのかわかりません。

ということで、C/C++でSegmentation faultが発生した場所を特定する方法を紹介します。

使用しているLinuxはCentOSです。

本来解としてコアダンプを解析する方法もありますが、そちらについては別途エントリーします。

2.Segmentation faultが発生した場所を特定する

Segmentation faultが発生した場所を特定するには、下記の環境変数を設定します。

% export LD_PRELOAD="/lib64/libSegFault.so"
% export SEGFAULT_SIGNALS="all"

上記は64bit版で、32bit版の場合は下記です。

% export LD_PRELOAD="/lib/libSegFault.so"
% export SEGFAULT_SIGNALS="all"

これでサンプルを実行すると、エラーの詳細が出力されます。

% ./a.out
*** Segmentation fault
Register dump:
 
 RAX: 0000000000000000   RBX: 0000000000000000   RCX: 0000000000400570
 RDX: 00007ffeeac84158   RSI: 00007ffeeac84148   RDI: 0000000000000001
 RBP: 00007ffeeac84050   R8 : 00007f197757ae80   R9 : 0000000000000000
 R10: 00007ffeeac83eb0   R11: 00007f19771e0a20   R12: 0000000000400440
 R13: 00007ffeeac84140   R14: 0000000000000000   R15: 0000000000000000
 RSP: 00007ffeeac84040
 
 RIP: 0000000000400544   EFLAGS: 00010202
 
 CS: 0033   FS: 0000   GS: 0000
 
 Trap: 0000000e   Error: 00000004   OldMask: 00000000   CR2: 00000000
 
 FPUCW: 0000037f   FPUSW: 00000000   TAG: 00000000
 RIP: 00000000   RDP: 00000000
 
 ST(0) 0000 0000000000000000   ST(1) 0000 0000000000000000
 ST(2) 0000 0000000000000000   ST(3) 0000 0000000000000000
 ST(4) 0000 0000000000000000   ST(5) 0000 0000000000000000
 ST(6) 0000 0000000000000000   ST(7) 0000 0000000000000000
 mxcsr: 1f80
 XMM0:  00000000000000000000000000000000 XMM1:  00000000000000000000000000000000
 XMM2:  00000000000000000000000000000000 XMM3:  00000000000000000000000000000000
 XMM4:  00000000000000000000000000000000 XMM5:  00000000000000000000000000000000
 XMM6:  00000000000000000000000000000000 XMM7:  00000000000000000000000000000000
 XMM8:  00000000000000000000000000000000 XMM9:  00000000000000000000000000000000
 XMM10: 00000000000000000000000000000000 XMM11: 00000000000000000000000000000000
 XMM12: 00000000000000000000000000000000 XMM13: 00000000000000000000000000000000
 XMM14: 00000000000000000000000000000000 XMM15: 00000000000000000000000000000000
 
Backtrace:
./a.out[0x400544]
./a.out[0x400566]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7f19771e0b15]
./a.out[0x400469]
 
Memory map:
 
00400000-00401000 r-xp 00000000 fd:02 139776506                          /home/foo/a.out
00600000-00601000 r--p 00000000 fd:02 139776506                          /home/foo/a.out
00601000-00602000 rw-p 00001000 fd:02 139776506                          /home/foo/a.out
00894000-008b5000 rw-p 00000000 00:00 0                                  [heap]
7f1976fa9000-7f1976fbe000 r-xp 00000000 fd:00 201326729                  /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f1976fbe000-7f19771bd000 ---p 00015000 fd:00 201326729                  /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f19771bd000-7f19771be000 r--p 00014000 fd:00 201326729                  /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f19771be000-7f19771bf000 rw-p 00015000 fd:00 201326729                  /usr/lib64/libgcc_s-4.8.5-20150702.so.1
7f19771bf000-7f1977375000 r-xp 00000000 fd:00 201329562                  /usr/lib64/libc-2.17.so
7f1977375000-7f1977575000 ---p 001b6000 fd:00 201329562                  /usr/lib64/libc-2.17.so
7f1977575000-7f1977579000 r--p 001b6000 fd:00 201329562                  /usr/lib64/libc-2.17.so
7f1977579000-7f197757b000 rw-p 001ba000 fd:00 201329562                  /usr/lib64/libc-2.17.so
7f197757b000-7f1977580000 rw-p 00000000 00:00 0
7f1977580000-7f1977584000 r-xp 00000000 fd:00 201329559                  /usr/lib64/libSegFault.so
7f1977584000-7f1977783000 ---p 00004000 fd:00 201329559                  /usr/lib64/libSegFault.so
7f1977783000-7f1977784000 r--p 00003000 fd:00 201329559                  /usr/lib64/libSegFault.so
7f1977784000-7f1977785000 rw-p 00004000 fd:00 201329559                  /usr/lib64/libSegFault.so
7f1977785000-7f19777a6000 r-xp 00000000 fd:00 201329555                  /usr/lib64/ld-2.17.so
7f197798e000-7f1977991000 rw-p 00000000 00:00 0
7f19779a5000-7f19779a6000 rw-p 00000000 00:00 0
7f19779a6000-7f19779a7000 r--p 00021000 fd:00 201329555                  /usr/lib64/ld-2.17.so
7f19779a7000-7f19779a8000 rw-p 00022000 fd:00 201329555                  /usr/lib64/ld-2.17.so
7f19779a8000-7f19779a9000 rw-p 00000000 00:00 0
7ffeeac64000-7ffeeac85000 rw-p 00000000 00:00 0                          [stack]
7ffeeacdd000-7ffeeacdf000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Segmentation fault (コアダンプ)

最後に、「Backtrace:」の最初に表示されたアドレスをaddr2lineコマンドで変換すると、エラーになったファイルと行番号が表示されます。

% addr2line -e a.out 0x400544
/home/foo/test.cc:6

なお、この情報を出力するには、g++でビルドする際に"-g"オプションが必要です。

簡単なサンプルでしか確認していないので、すべてのパターンに適用できるか分かりませんがとりあえず。

Comments [0] | Trackbacks [0]

IEのタブに色がつく理由

March 9,2017 12:03 AM
Category:[IE]
Tag:[IE, Windows]
Permalink

IEのタブに色がつく理由を調べてみました。

1.はじめに

IEで複数のタブを開くと、下のスクリーンショットのように色がつく場合があります。

複数のタブ

逆に色がつかない場合もありますが、その違いがわかりません。

ということで、IEのタブに色がつく理由を調べてみました。

2.タブに色がつく理由

タブに色がつくのは、あるページから新しいタブを開いたとき、色分けすることでタブのグループをわかりやすくするための仕組みです。

たとえばYahooのページのタブをひとつだけ開いているときは色がつきません。

タブをひとつだけ開いているとき

この状態でページ内の任意のリンクを新しいタブで開くと、タブに色がつきます。

新しいタブ

Yahooとは関係のない別のページを開い、そのページにある任意のリンクを新しいタブで開くと、異なる色がつきます。

新しいタブ

配色の順序はランダムのようです。

3.色分けをやめる

色分けをやめたいときは、「ツール」→「インターネットオプション」をクリック。

インターネットオプション

「全般」タブ→「タブ」をクリック。

タブ

「タブグループを有効にする」のチェックを外して「OK」をクリック。

タブグループを有効にする

IE再起動後、色分けがされなくなります。

再起動後

4.色分けされた状態でタブを移動した場合

色分けされた状態のタブを移動した場合、移動したタブの色は、

  • 移動先の左右のタブの色が同じ場合、その色に変わる
  • 移動先の左右のタブの色が異なる場合、解除

となるようです(個人的にはこの仕様はどうかと思いますが...)。

移動元のタブ色も最後の1つになると色が解除されます。

移動前
移動前

移動後
移動後

Comments [0] | Trackbacks [0]

C++で「invalid abstract type~」というエラーになる場合の対処

March 8,2017 12:03 AM
Category:[C/C++]
Tag:[C/C++]
Permalink

C++で「invalid abstract type~」「because the following virtual functions are pure within~」というエラーになる場合の対処方法について紹介します。

1.問題点

下記のサンプルプログラムを作りました。

sample.h

class Sample {
    public:
        Sample();
        void test1();
        virtual void test2() = 0;
};

sample.cc

#include <stdio.h>
#include "sample.h"
 
Sample::Sample() {
}
 
void Sample::test1() {
    printf("%s\n", "Hello World!");
}
 
void Sample::test2() {
}

test.cc

#include "sample.h"
 
Sample sample[10];
 
int main() {
    sample[0].test1();
    return 0;
}

このプログラムをコンパイルすると、下記の「invalid abstract type~」「because the following virtual functions are pure within~」というエラーに遭遇します。

% g++ test.cc sample.cc
test.cc:3:17: エラー: invalid abstract type 'Sample' for 'sample'
 Sample sample[10];
                 ^
In file included from test.cc:1:0:
sample.h:1:7: 備考:   because the following virtual functions are pure within 'Sample':
 class Sample {
       ^
sample.h:5:22: 備考:    virtual void Sample::test2()
         virtual void test2() = 0;
                      ^

2.原因

純粋仮想関数(pure virtual function)をもつクラスは抽象クラス(abstract class)となるので、その型のオブジェクトは定義できないようです。

3.対処

クラス定義をポインタ型にすることでこのエラーを回避できます。

#include "sample.h"
 
Sample *sample[10];
 
int main() {
    sample[0]->test1();
    return 0;
}

ポインタ型にするため、関数へのアクセスは"."ではなく、"->"に変更します。

4.参考サイト

参考サイトは下記です。ありがとうございました。

Comments [0] | Trackbacks [0]

標準エラー出力をlessで表示する方法

March 3,2017 12:03 AM
Category:[Linux]
Tag:[Linux]
Permalink

標準エラー出力をlessで表示する方法を紹介します。

1.問題点

LinuxでC++のビルド作業をしており、gccコマンドで数千ほどのファイルのリンケージを実行してます。

で、実行すると案の定、大量のエラーが出力され、ターミナルのスクロールバーを戻しても先頭のエラーを確認することができません。

標準出力であればパイプでつないでlessで確認できるのですが、次のようなコマンドを実行しても標準エラー出力をlessで拾えません。

% make | less

ということで、標準エラー出力をlessで表示する方法を紹介します。

ここではmakeコマンドを例にしていますが、他のコマンドでもこのお作法が使えると思います。

2.標準出力と標準エラー出力の両方をlessで表示する

標準出力と標準エラー出力の両方をlessで表示するには、次のコマンドを実行します。

% make 2>&1 | less

コマンドの意味は次のとおりです。

まずmakeを実行します。

次の"2>&1"で、標準エラー出力(2)を標準出力(1)と同じファイルディスクリプタにリダイレクトします。

これで標準エラー出力をlessで拾えるようになります。

3.標準エラー出力だけをlessで表示する

標準エラー出力だけをlessで表示するには、次のコマンドを実行します。

% make 2>&1 > /dev/null | less

2のコマンドと異なるのは「> /dev/null」が追加されていることです。

これは標準出力(1)を/dev/nullにリダイレクトする(=破棄する)ことを意味します。

厳密には「1> /dev/null」と書きますが、「>」と書くと1を省略している意味になります。

Comments [0] | Trackbacks [0]
 1  |  2  |  3  |  4  |  5  | All pages