Stack area

最近スタック領域とかエラそうなことを書いているけど。
よく考えたら実は何故スタック領域という名前なのかを知らない。
スタックってデータを後入れ先出しすることだよね。

#include <stdio.h>
#include <stdlib.h>

int
main (int argc, char* argv[]) {

    /* 自動変数はスタック領域 */
    int   i;        /* 4 byte 確保 */
    char  str1[6];  /* 6 byte 確保 */
    char* str2;     /* 8 byte (64bit の場合)確保 */

    /* NULL文字'\0'が入るので 5 byte 以下 */
    sprintf(str1, "%s", "Ninja");

    /* 256 byte をヒープ領域に確保 */
    str2 = malloc(256);
    sprintf(str2, "%s", "Kawasaki");

    for (i=0; i<2; i++)
        printf("%s %s\n", str2, str1);

    /* ヒープ領域確保分は解放する(確保を手放す)必要あり */
    free(str2);

    /* 解放されても別スレッドに上書きされるまでは残っている */
    printf("%s\n", str2);

    return 0;
}

ということさえ解っていれば別に意味は知らずとも…
ではイカンよな、もう少し理解しなきゃ。

学校では教えてくれないこと | 技術コラム集(組込みの門) | ユークエスト

そういう意味だったのか、宣言順に積み上がっていくのね。
ただ x86_64 だと 8 バイトでは上手くいかなかったので 16 に。

#include <stdio.h>
#include <string.h>

int
main (int argc, char* argv[]) {

    char a[16] = "元の文字列", b[16];

    printf("before a[]=<%s>\n", a);
    strcpy(b, "0123456789abcdef破壊");
    /*
     * ちなみにコチラだと Segmentation fault
     * sprintf("%s\n", b, "0123456789abcdef破壊");
    **/
    printf("after  a[]=<%s>\n", a);

    return 0;
}

buffer_over_run

なるほど、これは完全に後入れ先出しだ。

関数内の自動変数もスタックに入るから確かにコレが一番効率いいな。
スタックってそういう処理がしたい場合に利用するのか、うんうん。
それも解って得した気分。

しかしこういう gcc で解説してくれるサイトなんですが。
皆 stdio.h だけインクルードしているけど、筆者の環境では

strcpy を使う時は string.h
malloc を使う時には stdlib.h

と関数宣言されているヘッダを直インクルードしないと警告になる。
ビルドはできるけどね、警告が出るのって嫌じゃないですか。