プログラミング

[C言語]スペースを大量に入れるとバグが直るコードを書いてみた

投稿日:

↓こういうツイートがバズっていたので、実際に組んでみた。

バグのあるコード

たとえば、”hogehoge”という文字列の、”o”を”piyopiyo”に置換する、というプログラムをこう書く。
(2/22 11時追記:destのナル終端忘れていたので修正しました。ナル終端は今回のバグとは関係ないです)

#include <stdio.h>

void replace(char *dest, char *src) {
  while (*src != '\0') {
    if (*src != 'o') {
      *dest++ = *src++;
    } else {
      *dest++ = 'p';
      *dest++ = 'i';
      *dest++ = 'y';
      *dest++ = 'o';
      *dest++ = 'p';
      *dest++ = 'i';
      *dest++ = 'y';
      *dest++ = 'o';
      *src++;
    }
  }
  *dest = '\0';
}

void hoge() {
  char str1[] = "fuga";
  char str2[] = "";
  char str3[] = "hogehoge";
  replace(str2,str3);

  printf("%s\n", str2);
}

void main() {
  hoge();
}

実行してみる

hpiyopiyogehpiyopiyoge
Segmentation fault

この通り、なんとか動きはするがセグメンテーション違反を起こす。
ちなみにコンパイラはgcc。他の環境だと別の挙動になるかもしれない。

直ったコード

一見無関係に見える、”fuga”の部分にスペースを大量に注入する。

#include <stdio.h>

void replace(char *dest, char *src) {
  while (*src != '\0') {
    if (*src != 'o') {
      *dest++ = *src++;
    } else {
      *dest++ = 'p';
      *dest++ = 'i';
      *dest++ = 'y';
      *dest++ = 'o';
      *dest++ = 'p';
      *dest++ = 'i';
      *dest++ = 'y';
      *dest++ = 'o';
      *src++;
    }
  }
  *dest = '\0';
}

void hoge() {
  char str1[] = "fuga               "; // スペース注入
  char str2[] = "";
  char str3[] = "hogehoge";
  replace(str2,str3);

  printf("%s\n", str2);
}

void main() {
  hoge();
}

実行してみる

hpiyopiyogehpiyopiyoge

セグメンテーション違反しなくなる。

問題

さてここで問題です。

  1. そもそもなぜセグメンテーション違反していたのでしょうか。
  2. スペースを入れることでセグメンテーション違反が解決したのはなぜでしょうか。
  3. この直し方はもちろん正攻法ではありません。どう直すべきでしょうか。

C言語を学ぶ人は考えてみてください。正解はまわりのC言語ユーザーに聞いてみてね。
そしてC言語を学ばない人は「こんなクソみたいな言語一生使わんわ滅びろ」って思ってください。

-プログラミング

執筆者:

関連記事

どうして私はC言語で仕事をしているのか

みなさんプログラミング言語は学んでますか?今から始めますか? 最初に学ぶべきプログラミング言語ってなんだと思いますか?そうです。C言語です。 C#でもC++でもObjective-Cでもなく、Pure …

no image

[python]Windows環境でsubprocessするときは文字コードに気をつけて

pythonは内部の文字コードと実行環境の文字コードが色々絡み合っていて、いろんなところで悪さをする。 特にWindows環境だと、内部はUTF-8で動いているのに実行環境はShift-JIS(正確に …

GeoJSONで市町村境界をマージして都道府県境界にしたい(その1)

前回の続きで、国土地理院の「国土数値情報」っていうオープンデータで遊んでいます。独立した記事なので前回のは読まなくても良いです。 やりたいこと 国土数値情報で提供されている「行政区域データ」は、市町村 …

no image

C言語のポインタに関する補足説明

前回、C言語のポインタに関する解説記事を書きまして、そこそこの反響を貰うとともにいくつかの指摘を受けました。 前回の記事では幾つか「ウソではないけど真実と違う」記述がありまして、その点を補足としていく …

no image

Google Apps Script(GAS)で自宅サーバーの死活監視をする

前置き 自宅サーバー使ってますか? 最近もう流行らないかな、と思ったらRaspberry Piの流行で機器も電気代も安価に組めるようになったりして、地味に持っている人も多いんじゃないかな、と思ってます …