掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.24897

構造体について
投稿者---べた(2005/12/22 00:11:01)


構造体の使い方につてい教えてください。

以下の様な構造体が
typedef struct  {
    char        szErrMsg[16+1];
    long        lRetCode      ;
    short       shLineNo      ;
    char        szFreeInf[37+1];
} SYSLOG, *PSYSLOG ;


SYSLOGは、普通のタグ名を表していると思うのですが、
*PSYSLOGは、構造体のポインタのタグ名を表しているのでしょうか。

使用するときですが、

SYSLOG syslog;
PSYSLOG psyslog;

syslog.szErrMsg
psyslog->szErrMsg

でよいのでしょうか

変な内容ですみません。


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:構造体について 24898 wiz 2005/12/22 00:28:29
<子記事> Re:構造体について 24902 nop 2005/12/22 09:01:16


No.24898

Re:構造体について
投稿者---wiz(2005/12/22 00:28:29)


>SYSLOG syslog;
>PSYSLOG psyslog;
>
>syslog.szErrMsg
>psyslog->szErrMsg
>
>でよいのでしょうか

環境で制限がなければ、
それで使えると思います。

#質問する前に使ったほうが早いのでは。。。?



この投稿にコメントする

削除パスワード

No.24902

Re:構造体について
投稿者---nop(2005/12/22 09:01:16)


> typedef struct  {
>     char        szErrMsg[16+1];
>     long        lRetCode      ;
>     short       shLineNo      ;
>     char        szFreeInf[37+1];
> } SYSLOG, *PSYSLOG ;
> SYSLOGは、普通のタグ名を表していると思うのですが、
> *PSYSLOGは、構造体のポインタのタグ名を表しているのでしょうか。

SYSLOG、PSYSLOG 共にタグ名ではなく、typedef 名です。
SYSLOG は構造体の typedef 名、
PSYSLOG は構造体へのポインタの typedef 名となります。



この投稿にコメントする

削除パスワード

No.24958

Re:構造体について
投稿者---べた(2005/12/24 12:32:41)


解説、説明ありがとございます。



この投稿にコメントする

削除パスワード

No.24959

Re:構造体について
投稿者---べた(2005/12/24 15:04:28)


ソースを書いてみました。
>SYSLOG syslog;
>PSYSLOG psyslog;
>
>syslog.szErrMsg
>psyslog->szErrMsg
で使えました。

少々、質問があるのですが、
構造体を初期化しようと、memset関数を使用して、NULL(\0)に初期化しました。

SYSLOG syslog で宣言した構造体のサイズを表示しようとしたのですが、本来でしたら
typedef struct  {
    char  szErrMsg[16+1] ;
    long  RetCode ;
    short LineNo ;
    char  szFreeInf[37+1] ;
} SYSLOG ;

char型:17バイト + long型:4バイト + short型:2バイト+char型:38バイトで、
合計:61バイトになると思うのですが、実際には、64バイトと表示されてしまいます。
なぜなのでしょうか。
ソース1参照。

SYSLOG syslog は、実体を宣言しているので、構造体がNULLで初期化されれますが、
PSYSLOG psyslogは、ポインタの宣言なので、memsetをしてしまうと、アドレスを
NULLにしてしまうので、動作がおかしくなるのではないかと思ったですが、見た目
上は、動いてくれました。
本来は、領域を確保した方がよいのでしょうか。
また、領域を確保する際、確保する構造体のサイズを自動で取得したいのですが、
どうすればよいのですか。
ソース2参照。

ソース1
#include <stdio.h>

typedef struct  {
    char  szErrMsg[16+1] ;
    long  RetCode ;
    short LineNo ;
    char  szFreeInf[37+1] ;
} SYSLOG ;

void MsgDisp(SYSLOG *tsyslog)
{
    printf("%s,%d,%d,%s\n",tsyslog->szErrMsg, tsyslog->RetCode, tsyslog->LineNo, tsyslog->szFreeInf) ;
}

main()
{
    SYSLOG tsyslog ;

    printf("size = %d\n",sizeof(SYSLOG)) ;
    memset(&tsyslog, 0x00, sizeof(SYSLOG)) ;

    strcpy(tsyslog.szErrMsg,"fopen") ;
    tsyslog.RetCode = -1 ;
    tsyslog.LineNo = 0 ;
    strcpy(tsyslog.szFreeInf,"No such file or directory") ;

    MsgDisp(&tsyslog) ;
}


ソース2
#include <stdio.h>

typedef struct  {
    char  szErrMsg[16+1] ;
    long  RetCode ;
    short LineNo ;
    char  szFreeInf[37+1] ;
} *PSYSLOG ;

void MsgDisp(SYSLOG *tpsyslog)
{
    printf("%s,%d,%d,%s\n",tpsyslog->szErrMsg, tpsyslog->RetCode, tpsyslog->LineNo, tpsyslog->szFreeInf) ;
}

main()
{
    PSYSLOG tpsyslog ;

    memset(tpsyslog, 0x00, sizeof(PSYSLOG)) ;

    strcpy(tpsyslog->szErrMsg,"fopen") ;
    tpsyslog->RetCode = -1 ;
    tpsyslog->LineNo = 0 ;
    strcpy(tpsyslog->szFreeInf,"No such file or directory") ;

    MsgDisp(tpsyslog) ;
}



この投稿にコメントする

削除パスワード

No.24962

Re:構造体について【訂正】
投稿者---べた(2005/12/24 15:14:19)


訂正します。
ソース2が間違っていました。
修正したのを記載します。

ソース2
#include <stdio.h>

typedef struct  {
    char  szErrMsg[16+1] ;
    long  RetCode ;
    short LineNo ;
    char  szFreeInf[37+1] ;
} *PSYSLOG ;

void MsgDisp(PSYSLOG tpsyslog)
{
    printf("%s,%d,%d,%s\n",tpsyslog->szErrMsg, tpsyslog->RetCode, tpsyslog->LineNo, tpsyslog->szFreeInf) ;
}

main()
{
    PSYSLOG tpsyslog ;

    printf("size = [%d]\n",sizeof(PSYSLOG)) ;
    memset(tpsyslog, 0x00, sizeof(PSYSLOG)) ;

    strcpy(tpsyslog->szErrMsg,"fopen") ;
    tpsyslog->RetCode = -1 ;
    tpsyslog->LineNo = 0 ;
    strcpy(tpsyslog->szFreeInf,"No such file or directory") ;

    MsgDisp(tpsyslog) ;
}



この投稿にコメントする

削除パスワード

No.24963

Re:構造体について【訂正】
投稿者---Blue(2005/12/24 15:23:33)


> ソース1
構造体のアライメントについて調べてみてください。

> ソース2
これ本当に動きますか?
tpsyslogの指す領域はどこでしょうか?
コンパイルはとおりますか?

memsetはポインタの指す領域を初期化します。
ポインタ自体をNULLにするわけではありません。

よって、
> memset(tpsyslog, 0x00, sizeof(PSYSLOG)) ;
のsizeofしていは間違っています。
# 無名構造体で、ポインタ用にしかtypedefしていないので指定できないが。。。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct  {
    char  szErrMsg[16+1] ;
    long  RetCode ;
    short LineNo ;
    char  szFreeInf[37+1] ;
} SYSLOG, *PSYSLOG ;

void MsgDisp(PSYSLOG tpsyslog)
{
    printf("%s,%d,%d,%s\n",tpsyslog->szErrMsg, tpsyslog->RetCode, tpsyslog->LineNo, tpsyslog->szFreeInf) ;
}

int main( void )
{
    PSYSLOG tpsyslog = NULL;
    
    tpsyslog = ( PSYSLOG )malloc( sizeof( SYSLOG ) );

    printf("size = [%d]\n",sizeof(SYSLOG)) ;
    memset(tpsyslog, 0x00, sizeof(SYSLOG)) ;

    strcpy(tpsyslog->szErrMsg,"fopen") ;
    tpsyslog->RetCode = -1 ;
    tpsyslog->LineNo = 0 ;
    strcpy(tpsyslog->szFreeInf,"No such file or directory") ;

    MsgDisp(tpsyslog) ;

    free( tpsyslog );

    return 0;
}



この投稿にコメントする

削除パスワード

No.24964

Re:構造体について【訂正】
投稿者---べた(2005/12/24 15:32:46)


ありがとうございます。

ソース2ですが、一応は、動いています。
「fopen,-1,0,No such file or directory」を表示します。

偶然。バグを発生される処理がないからですか。

環境は、
Solaris8
UNI-C
gcc
gcc -o 実行モジュール ソースファイル



この投稿にコメントする

削除パスワード

No.24965

Re:構造体について【訂正】
投稿者---Blue(2005/12/24 15:37:46)


ほんとうですか?

コンパイルしようとしたら、
strcpyやmemsetが定義されていないとでます。
(gccではstdio.hだけですべてカバーできるのか?)

> tpsyslogの指す領域はどこでしょうか?
は?

int* p;
scanf( "%d", p );

とおんなじことやっているけど、Solaris8では大丈夫なんだ。
(*゜〜゜)ふぅぅぅん



この投稿にコメントする

削除パスワード

No.24966

Re:構造体について【訂正】
投稿者---Blue(2005/12/24 15:44:45)


>コンパイルしようとしたら、
>strcpyやmemsetが定義されていないとでます。
>(gccではstdio.hだけですべてカバーできるのか?)
は、手元に gcc があったので、コンパイルしたらできました。
VC++とは違うんですかねぇ。

まぁ、WindowsXPで実行したら、お決まりの
「問題が発生したため、〜を終了します。ご不便をおかけして申し訳ありません。」
がでましたが。


この投稿にコメントする

削除パスワード

No.24968

Re:構造体について【訂正】
投稿者---Hermit(2005/12/24 16:01:47)


>は、手元に gcc があったので、コンパイルしたらできました。
>VC++とは違うんですかねぇ。

Cは、

OLD C
PreANSI C
ANSI C
ANSI99 C

大きく分けると、これだけあります。
gcc は、ANSI C + 拡張機能 です。
(拡張機能の多くは ANSI99 で採用されてますが)


この投稿にコメントする

削除パスワード

No.24990

Re:構造体について【訂正】
投稿者---Blue(2005/12/27 14:04:56)


>べた氏
こちらは放置ですか?
構造体のアライメントについては理解できたのでしょうか?
ポインタ変数については理解できたのでしょうか?
私は放置が一番嫌いです。(怒)
> ソース2ですが、一応は、動いています。 >「fopen,-1,0,No such file or directory」を表示します。 は、実際どうなのでしょうか? Solaris8環境では、初期化も、割り当てもしていないポインタ変数にアクセスできるのでしょうか? カナリ気になるのですが。 # 私は環境がないので試しようがないです。 どなたか、ご教授ください。



この投稿にコメントする

削除パスワード

No.24991

Re:構造体について【訂正】
投稿者---べた(2005/12/27 20:58:39)


><pre>>べた氏
こちらは放置ですか?
構造体のアライメントについては理解できたのでしょうか?
ポインタ変数については理解できたのでしょうか?
<center><font color="white"><b>私は放置が一番嫌いです。(怒)</b></font></center>

データを4で割り切れる場所(4で割ることのできる番地)にデータを置くので、
足りない分、隙間を空けて調整している。
そのため、隙間分が空けられる。

構造体のサイズは、最大の長さを持つ要素の整数倍に等しくするというこおとから、
アライメントから起こる制約とのこです。
こんな制約があるのは、こうしないと配列にしたときに後続する構造体のアライメント
が滅茶苦茶なるからということです。


「__attribute__ ((packed))」を使って宣言をすれば、隙間をわざと埋めてくれる
らしいです。


この投稿にコメントする

削除パスワード

No.24972

Re:構造体について
投稿者---nop(2005/12/26 08:52:17)


>char型:17バイト + long型:4バイト + short型:2バイト+char型:38バイトで、
>合計:61バイトになると思うのですが、実際には、64バイトと表示されてしまいます。
>なぜなのでしょうか。

パディング(詰め物)が入るためです。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧