プログラミング

[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言語を学ばない人は「こんなクソみたいな言語一生使わんわ滅びろ」って思ってください。

-プログラミング

執筆者:

関連記事

no image

例え話をしないC言語のポインタの説明

もくじ1 まえおき2 Hello, Worldより簡単に2.1 サンプルコード2.2 変数の置き場所2.3 変数が入っているところを見てみる3 C言語とメモリ3.1 変数cの「まわり」を見てみる3.2 …

no image

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

もくじ1 前置き2 概要3 できあがり3.1 GAS側3.2 自宅サーバー側4 解説5 蛇足1 ログを取る6 蛇足2 サーバーをタイマ起動させて監視 前置き 自宅サーバー使ってますか? 最近もう流行ら …

no image

ランダムな日本人データを生成するツールをつくった

もくじ1 前置き2 完成!3 用いたデータについて4 中で何をしているのか4.1 基本アイデア4.2 累積確率の計算4.3 高速化の工夫5 おわりに 前置き ダミーの名簿データが作りたい、という需要は …

no image

SwitchBotの温湿度計、防水かどうかでBluetoothのデータの取り方違うぞ

SwitchBotは機器のAPIを公開していて、ユーザーの自作プログラムからBluetooth(BLE)越しにデータが取れたりします。 特に温湿度計のデータを取りたいというニーズは強くて、安価で安定し …

no image

UnityのCompute Shaderに線分と三角形の衝突判定をさせる

はじめてCompute Shader使ってみた。でもあまり性能は出ないのでただの失敗の記録です。 まず元のアルゴリズムはコレ。 線分と三角形の当たり判定 – 富士見研究所 で、これをまず三角形の表裏問 …