プログラミング

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

-プログラミング

執筆者:

関連記事

国土地理院の地図データをUnityで読みたい(願望)

なんかgoogleのAdSense通ったんで有益な情報載せないとなって。 国土地理院のオープンデータ 国土地理院が公開している(正確には国土地理院のデータを利用して国土交通省国土政策局国土情報課が公開 …

no image

Google Apps Script (GAS)でBlueskyのbotを作る

Blueskyで何かやりたくなったので、PRTimesのプレスリリースを自動投稿するbotを作ってみました。 Google Apps Scriptを使うと、無料でbotが作れるので便利です。 せっかく …

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

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

no image

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

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

SHOWROOMのガチイベをGoogleスプレッドシートでグラフにしよう

まえがき SHOWROOMのガチイベ、と言えば配信者が獲得ポイント数でランキングされ、最終的にファンの札束で殴り合って勝者を競う札束タワーバトルなわけです。 数日~数週間にわたって配信者同士でランキン …