dポイントプレゼントキャンペーン実施中!

固定要素数の行列の処理ですが、subでセグメントエラーを起こしています。
アドレスを出力してみると、subでは元々確保したアドレスでは無いところを指しています。
呼び出し側では「行列の先頭のアドレス」を明示したつもりだったのですが、どこが間違っているのでしょうか。少し長いですが、ソースコードと出力を示します。
typedefのところとsubのIFは変更できないので、double[3][3]とdouble** のIFを合わせないといけないのですが、合わせ方がよくわかりません。
よろしくお願いします。

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

typedef double Matrix[3][3];

void sub( const double** mat );

int main(void)
{

 int ret = 0;
 int i, j;

 Matrix mat = { { 0., 1., 2. },
     { 3., 4., 5. },
     { 6., 7., 8. } };
 
 for( i = 0; i < 3; i++ ){
  for( j = 0; j < 3; j++ ){
   printf( "main : mat[%d][%d] = %f\n", i, j, mat[i][j] );
   printf( "main : &mat[%d][%d] = %p\n", i, j, &mat[i][j] );
  }
 }
 printf( "\n" );

 sub( &mat[0][0] );

 return ret;
}

void sub( const double** mat )
{
 int i, j;
 printf("---- &mat = %p\n", &mat );
 for( i = 0; i < 3; i++ ){
  for( j = 0; j < 3; j++ ){
   printf( "sub : mat[%d][%d] = %f\n", i, j, mat[i][j] );
   printf( "sub : &mat[%d][%d] = %p\n", i, j, &mat[i][j] );
  }
 }
 printf( "\n" );
}

=========================================
main : mat[0][0] = 0.000000
main : &mat[0][0] = 0x7ffffca7bca0
main : mat[0][1] = 1.000000
main : &mat[0][1] = 0x7ffffca7bca8
main : mat[0][2] = 2.000000
main : &mat[0][2] = 0x7ffffca7bcb0
main : mat[1][0] = 3.000000
main : &mat[1][0] = 0x7ffffca7bcb8
main : mat[1][1] = 4.000000
main : &mat[1][1] = 0x7ffffca7bcc0
main : mat[1][2] = 5.000000
main : &mat[1][2] = 0x7ffffca7bcc8
main : mat[2][0] = 6.000000
main : &mat[2][0] = 0x7ffffca7bcd0
main : mat[2][1] = 7.000000
main : &mat[2][1] = 0x7ffffca7bcd8
main : mat[2][2] = 8.000000
main : &mat[2][2] = 0x7ffffca7bce0

---- &mat = 0x7ffffca7bc68
セグメンテーション違反です

A 回答 (14件中11~14件)

>(*mat)[3]


>という具合に、sub関数に渡す引数を

念のため。
こういう風に書く(必要があるかもしれない)のは、
関数プロトタイプ宣言や
関数の実体定義における引数の記載部分です。
    • good
    • 0
この回答へのお礼

2度もご回答ありがとうございます。
どうしてもリテラルが入ってしまうんですね…。

お礼日時:2011/01/02 14:21

>matの宣言はポインタのポインタでなく、*を1つでよいのでは?



さすがに、それはまずいでしょう。
そういうソースコードを書いて、ご自分で試してみましたか?

>以下、質問者さんへ
いわゆる2次元配列(各要素が配列であるような配列)と
ダブルポインターとは似て非なるものでありまして、
今回の例だと
(*mat)[3]
という具合に、sub関数に渡す引数を
「要素数3の配列へのポインター」とする必要があるかもしれませんし、
もっといい方法があるのかもしれません。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
配列とポインタは本当は違うものだという解説は、以前どこかで読んだことがあって、その時は「なるほどな~」と思ったものですが、やはり完全に理解できていなかったようです。
本当は、引数の「double**」の他にも引数があって、当然ですが行と列の要素数も引数にあります。この質問では、要素数固定として簡略化したんですが、ダブルポインタの箇所そのものを変更する必要があるかも、ということですね。

お礼日時:2011/01/02 14:15

void sub( const double** mat )



matの宣言はポインタのポインタでなく、*を1つでよいのでは?
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
*を1つだと、たぶん意味が違います…。

お礼日時:2011/01/02 14:07

>  sub( &mat[0][0] );



ここで警告出てませんか?
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
以下のワーニングがでています(Borland)。

Warning W8075 main.c 30: Suspicious pointer conversion in function main

gccでも同じような意味のものが出ていたと思います。

お礼日時:2011/01/02 14:06

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!