pit-rayの備忘録

ゲームやソフトウェアの開発にて得た知識や制作活動の途中経過をまったり書いていくブログ。

気を抜いたら負け

あぁ...
刻々と違づくセンター試験

残るもあと97日

勉強を好きになりたいとおもう

べんきょ、たのし
おかず、べんきょ
べんきょ、だいすき
べんきょ、べんきょ
かのじょべんきょ
べんきょ
べんんきょきょきょきょ
べんきょ

頭がおかしくなりそうだ

というのは嘘で、めちゃくちゃ気が楽だ


「俺って、笑いながら死ねる系の人だ」

と思ってる


こんなにも危機的状況なのに危機感一切ない


取り敢えず、言いたかったこ



まぁ受かるからみてろ

今日の日記

部屋にあるペットボトル捨てました

模試が死にました

 

これはマクドナルドです

一瞬で消え失せる学習意欲

学習意欲は何次関数かは知らないが、金曜が極大値で今は極小値へと降下中である。

今日は残りオールしてサボった分を取り戻そうと思う。

 

 

 

今日の一言。

 

 

 

無印良品ってイイね!

日記を書くことにした

備忘録とか言いながら日記を書くことにした。

 

何故に今の時代になって日記(ブログ)なのかというと、単なるストレス発散である。他にも日記の醍醐味である過去の自分を後に見直して笑ったり反省したりするためでもある。

 

話が飛ぶ気がするが、某有名なYouTuberであるHIKAKIN氏も動画で同じようなことを言っていた気がする。あの人は有名になった後も自分のキャラというものを確立させ、さらに視聴者を飽きさせないという驚くべきことを毎日成し遂げているのである。我ら凡人には想像もつかないような苦労がそこにはあるのだろう。しかしながら、あまりにも絶賛しているとヒカキッズなどと言われかねないので、これくらいにしておきたい。(ネトウヨがすぐヒカキッズと馬鹿にするのは偏見だろうか...)

 

先ほどYouTubeを話題に出したが、試験のため、スマホからYouTubeTwitterのアプリを消しているのでYouTubeの現状は知らない。このように勉強前にアプリを消したり、部屋の掃除をし始めるのは、典型的な落ちる受験生と言われればぐうの音も出ない。個人的に教材を買って、それで満足感に浸っている輩が落ちると思います。試験を受けてないのになにを言ってるのだか...

 

本日は9月9日。

試験まであまり時間がない。

受験勉強は殆どしていないため、模試などを活用して対症療法的学習をしたいと考える。考えるだけじゃなくてしなくちゃ。〜学習をする。

 

頭の中を整理するのは大事。

だから毎日のことを書いていくと思う。

 

今読み返したら、僕の文章って句読点少なくて読みにくいことに気がついた。

何故なら、この文章は、"やはり俺の青春ラブコメは間違っている"のライトノベル風に書いたものである。結構そのときの本の書き方に影響される僕であった。

 

 

構造体へのポインタの初期化

今回もC言語についての備忘録になります。

 

今回のトピックは

構造体へのポインタの初期化

です。(タイトルにもありますが)

 

これは初歩的なミスです。

しかし、私は初心者故、最近こいつとバトルしました。

まず、悪い例のソースコードはこちら。

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

typedef struct _Position {
    int x ;
    int y ;
} Pos ;

void AddOne( Pos *hoge  ) {
    hoge->x ++ ;
    hoge->y ++ ;
    return ;	
}

int main( void ) {

    Pos *temp ;

    temp->x = 10 ;
    temp->y = 20 ;
    
    printf( "BeforePosition(%d,%d)", temp->x, temp->y ) ;

    AddOne( temp ) ;
	
    printf( "AfterPosition(%d,%d)", temp->x, temp->y ) ;

    return ;
}

 

今回私がVisual Studioにて吐かれたエラーは

***.exe の0x0164536Eで初回の例外が発生しました: 0xC0000005: 場所 0x00000000 を読み込み中にアクセス違反が発生しました。

というものです。

 

調べるとこのエラーは大概、初期化されていないポインタを使用した場合に吐かれるらしいです。

これは

ポインタの定義だけではメモリが確保されない

ことが原因です。

 

その為、

一度メモリを確保してゼロクリア

すれば初期化できます

メモリを動的確保をしているため、最終的に使い終わったらメモリを開放しなくてはいけません。

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

typedef struct _Position {
    int x ;
    int y ;
} Pos ;

void AddOne( Pos *hoge  ) {
    hoge->x ++ ;
    hoge->y ++ ;
    return ;	
}

int main( void ) {

    Pos *temp ;
	
    temp = ( Pos * ) malloc( sizeof( Pos ) ) ;
    memset( temp, 0, sizeof( Pos ) ) ;

    temp->x = 10 ;
    temp->y = 20 ;
    
    printf( "BeforePosition(%d,%d)", temp->x, temp->y ) ;

    AddOne( temp ) ;
	
    printf( "AfterPosition(%d,%d)", temp->x, temp->y ) ;

    free( temp ) ;
    return ;
}

 

 

この赤字で示した箇所が追加したコードです。

 

数分でぱぱっと書いたソースコードなので誤りがあったらご指摘ください。

 

以上、備忘録でした。

ポインタ型の構造体を定義するときはメモリを確保して初期化するようにしましょう。

 

大学受験で病み気味

今日も終わりへと近づいて来ました23:50。

実は高校生である私は偏差値10くらい上の大学を志望してるのである。

無謀である。

 

というのは冗談で、結構イケる自信がある。

 

勿論点数を取れてないのは事実だが、内容が分からないわけではなく、単に定着してないだけだ。

これは落ちる受験生の定番の決め台詞だろうか。

 

まぁいい。

勉強するしかない。

 

あぁ、開発の時間が無くなる...(´;ω;`)

 

とはいうものの、ここ2年、リファクタリングと3DCGに没頭していて、あっという間に過ぎた。正直、個人開発つらみ。

 

そんなこんなで一切需要がない記事であった。

おやすみ。

 

malloc()+memset()とcalloc() ゼロクリアする場合における違い

今回は開発していて気になったことがあったのでググってみました。

言語はCです。

 

最初の記事にも書いたのですが、私自身、プログラミング歴が長いわけではないため、信憑性はかなり低いものとなっております。

ネットサーフィンの基本ですが、より意識して情報の取捨選択をお願いします。

 

 

 

まず、今回気になったことは

malloc()+memset()によるゼロクリアとcalloc()によるゼロクリアは何が違うのだろうか

ということです。

 

まず、それぞれの関数の定義等を見ていきましょう。

 

メモリ確保を行う関数。stdlib.hに定義されている。

定義:void *malloc(size_t size)

戻り値:確保したメモリの先頭アドレス

参考:malloc - Wikipedia

 

  • memset

指定したメモリブロックから指定したバイト数の範囲に指定した文字データを書き込む関数。string.hに定義されている。

つまりは、指定した範囲を指定した文字で埋める関数です。

今回はこの関数を利用して上記のmalloc関数で確保したメモリをmemset関数で初期化(ゼロクリア)するということです。(このことを以下malloc()+memset()と略す )

定義:void *memset(void *s, int c, size_t)

戻り値:sの先頭アドレス

参考:memset - Wikipedia

 

  • calloc

メモリの確保とその初期化(ゼロクリア)する関数。stdlib.hに定義されている。

これはmalloc関数にゼロクリア機能が付いたもの。

定義:void *calloc(size_t nelements, size_t bytes)

戻り値:確保したメモリの先頭アドレス

参考:malloc-関連する関数 - Wikipedia

 

ここでmemset()の初期化処理とcalloc()の初期化処理は何が違うのかということが気になったわけです。

その為、ググってみたところ、以下のようなページがありました。

c - Why malloc+memset is slower than calloc? - Stack Overflow

ここのAnswersに以下のように書かれていたため、高校生レベルの英語力である私が軽く適当に訳してみました。(weblioGoogle翻訳を使用)

 The short version: Always use calloc() instead of malloc()+memset(). In most cases, they will be the same. In some cases, calloc() will do less work because it can skip memset() entirely. In other cases, calloc() can even cheat and not allocate any memory! However, malloc()+memset() will always do the full amount of work.

 

 

要約文:常にmalloc()+memset()の代わりにcalloc()を使用してください。殆どの場合、それらは同じものとして機能するでしょう。場合によってはcalloc()は完全にmemset()をスキップし得るので、より少ない仕事をするでしょう。 (calloc()はmemset()の簡易版的な意味合いだろうか)他の場合では、calloc()は少しもメモリを割り当てることが出来ず、誤魔化すことすらあり得ます。しかしながら、malloc()+memset()は全ての仕事量をこなします。

 この訳は全く持って正しいものではないので、他サイトなどに転載しないようにご協力お願いします。ここでは大体の意味を掴むために訳しております。

 

つまり、memset()のほうがcalloc()よりも確実にゼロクリアを行うといった感じでしょうか。

 

しかし、上記の参考サイトの質問者が仰っている通り、calloc()のほうがmemset()+malloc()よりも高速らしいです。

この件に関しての記事がありました。

malloc+memsetとcallocの違いについて

 

私の記事よりも詳しく書かれています。

もう少し深いところを知りたい場合、是非アクセスしてみてください。

 

結果的に言いますと、どちらがイイとは言えません。

どちらもそれぞれメリット・デメリットがあるみたいです。

素人の私にしてみるとお腹一杯です...(;´Д`)

 

まとめると

Q -ゼロクリアするうえでのmemset()とcalloc()の違いは?

A -「確実性」memset() >calloc()

  「速度面」memset()<calloc()

といった感じでしょうか。

 

何かこの記事にご不明な点や変な個所がありましたら、コメントにて指摘して頂けると幸いです。また、私は初心者みたいなものなので、意見など書いていただけると助かります。

何度も言いますが...

あくまで備忘録であることをお忘れなく。

それではまたの機会に会いましょう。

☆。.:*:・'゜ヽ( ´ー`)ノ まったね~♪