pit-rayの備忘録

開発中に得た知識を記事にしていくブログ

<C言語>構造体へのポインタの初期化

今回も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 ;

}

 

 

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

 

わざわざ、実体を動的に作る機会はあまりないと思いますが、参考になったら幸いです。

 

コードに誤りがあったらご指摘ください。

 

以上、備忘録でした。

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