初めて書き込みする,taroimotenです.

以下のプログラムを作ってみたのですが,
メモリ参照エラーが表示され,うまく動きません.
アドバイスおねがいします!


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

// 型宣言.
typedef struct data DATA;
typedef struct coords COORDS;

// 構造体の定義.
struct data{
COORDS *pnt[3];
};

struct coords{
float r1;
float r2;
};

int main(void)
{

DATA *ptr;
DATA x;

// ポインタ変数の初期化.
ptr = &x;

// メンバへの値の代入.
ptr->pnt[0]->r1 = 100.0;

printf(" r1 : %f \n",ptr->pnt[0]->r1);

return EXIT_SUCCESS;

}

A 回答 (5件)

あの。

。。
もう一点。

COORDS *mem_ptr;
mem_ptr = (COORDS *)malloc(sizeof(COORDS *));
ptr->pnt[0] = mem_ptr;

というコードですが、大丈夫ですか?
私には、4バイトのメモリアロックしかされていないように見えますが。。。
Floatを2つだから、8バイト×2で16バイトを取らないといけないのでは。。。

このコードは、
COORDS *mem_ptr;
mem_ptr = (COORDS *)malloc(sizeof(COORDS));
ptr->pnt[0] = mem_ptr;
としないと、コンパイルは通っても、バグが出ると思います。

では、再レスでした。
    • good
    • 0
この回答へのお礼

goukunさん,度重なるアドバイスありがとうございます.
貴君の↓おっしゃるとおりですね.

COORDS *mem_ptr;
mem_ptr = (COORDS *)malloc(sizeof(COORDS *));
ptr->pnt[0] = mem_ptr;

というコードですが、大丈夫ですか?
私には、4バイトのメモリアロックしかされていないように見えますが。。。
Floatを2つだから、8バイト×2で16バイトを取らないといけないのでは。。。

今後とも宜しくです.では.

お礼日時:2001/08/23 16:56

再補足で、処理を修正してみました。


(余計なお世話かな?)

きっと、こうならないと、コンパイルでエラーが出ると思います。
No.1の方のお答えに合わせて修正して見たソースです。

ではでは。

----<ソース>--------
#include <stdio.h>
#include <stdlib.h>

// 型宣言.
// typedef struct data DATA;
// typedef struct coords COORDS;

// 構造体の定義.
typedef struct coords{
float r1;
float r2;
}COORDS;

typedef struct data{
// COORDS *pnt[3];
COORDS pnt[3];
}DATA;

int main(void)
{

DATA *ptr;
DATA x;

// ポインタ変数の初期化.
ptr = &x;

// メンバへの値の代入.
ptr->pnt[0].r1 = 100.0;

printf(" r1 : %f \n",ptr->pnt[0].r1);

return EXIT_SUCCESS;

}
    • good
    • 0
この回答へのお礼

goukun さん,たびたびアドバイスありがとうございます.

うーん,わかりやすくコードですね.
参考にさせて頂きます.

また,何かありましたら、 御指導おねがいいたします.

では.

お礼日時:2001/08/23 15:18

No.1で回答したnaturalです。


失礼しました。(^_^;
読み間違いです。
参照方法はあっていますが、ポインタpntの先に実体がぶら下がっていないことが原因です。
書き込み・読み込むべき領域が存在しないために出ているエラーなので、coords型の変数領域を割り当ててあげる必要があります。
    • good
    • 0
この回答へのお礼

naturalさん,さっそくの返答ありがとうございます.
以下の行を付け加えたら動きました.

COORDS *mem_ptr;
mem_ptr = (COORDS *)malloc(sizeof(COORDS *));
ptr->pnt[0] = mem_ptr;

では.

お礼日時:2001/08/23 15:04

私からの補足です。



struct data{
COORDS *pnt[3];
};
となっていますが、これ、ポインタですよね。
アドレスを格納しないと、メモリ参照エラーがでますよ。

ではでは。
    • good
    • 0

>ptr->pnt[0]->r1 = 100.0;



ptr->pnt[0].r1 = 100.0;
です。

>printf(" r1 : %f \n",ptr->pnt[0]->r1);

同じく
printf(" r1 : %f \n",ptr->pnt[0].r1);
です。

ポインタptrで参照した先のpnt[0]は実体だからです。
実体のメンバー参照は「.(ドット演算子)」で行います。
    • good
    • 0

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

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qダイアログからビュークラスのメンバ変数へ代入するには?

プログラミング初心者です.
Visual C++.netを使っています.

Viewクラスから,Domodal()にてあるダイアログを呼び出しました.
ダイアログ上のあるボタンを押したら,Viewクラスのメンバ変数へ1を代入するという処理をしたいと考えています.
 ラジオボタンやエディタコントロールであれば,DDXを利用すればよいと思うのですが,単なるボタンの場合はどうすれば,呼び出し元のViewクラスの値を操作(この場合,代入)出来るのでしょうか?

Aベストアンサー

ダイアログのコンストラクタに変数を増やすなどして、Viewクラスのポインタをダイアログに登録します。

ダイアログのボタンクリックハンドラで既に登録されているViewクラスのポインタを使用して希望の変数を変更するとできます。

これは色々な方法があります。

逆にダイアログクラスにボタンのクリック結果を変数として残しておき、ダイアログが終了してからダイアログのクリック結果をViewクラスが確認する方法もあります。

他には、ダイアログのボタンクリックハンドラから、Viewクラスへメッセージを送信するという方法もありますね。

色々有るので色々勉強してくださいね。

Q{x = x>y ? x:y; return x;}

#include <iostream>
using namespace std;

inline int max(int x, int y){x = x>y ? x:y; return x;}

int main()
{
int num1, num2, ans;

cout << "2つの整数を入力して。\n";
cin >> num1 >> num2;

ans = max(num1, num2);

cout << "最大値は" << ans << "です。\n";

return 0;
}
の{x = x>y ? x:y; return x;}の部分の意味が解りません。

Aベストアンサー

inline int max(int x, int y){x = x>y ? x:y; return x;}
これを普通に関数で書くと

int max(int x, int y)
{
x = x>y ? x:y;
return x;
}

です。

x = 部分は右辺の結果が代入されます。これはわかりますよね。
x>y?x:y;
と書くと?より左にある条件式を判定し、その結果が真である場合は:で区切られた左側の値を、偽である場合は右の値を帰します。
x>yが真であればxを、偽であればyを返します。
それが、左辺値xに代入され、関数の戻り値として帰ります。

従って、2つの値をこの関数に入れると、大きいほうの値が帰ることになります。

Q構造体メンバ 構造体ポインタ 値代入

typedef struct _test_t{
int aaa;
int bbb;
} test_t;

typedef struct _globalData{
int xxx;
test_t* pTestData[256];
} globalData_t;

globalData_t globalData;


int main(){

test_t testData1 = {1,1};
test_t testData2 = {2,2};

*globalData.pTestData[1] = testData1; /* (1) */

globalData.pTestData[2] = &testData1; /* (2) */

}

上記のようなグローバルデータの構造体globalData
のメンバの構造体配列にtest_t型の構造体を格納し保持するには、
(1)、(2)のどちらが正しいでしょうか?

Aベストアンサー

> 代入、*globalData.pTestData[xxx] = testData1;
> 削除 *globalData.pTestData[xxx] = NULL;

削除時点でヌルポインタになってしまうので、ご所望の書き方では削除後に代入はできません。
ちなみに削除はアスタリスクを取って
globalData.pTestData[xxx] = NULL;
が正しいと思います。

なぜNULLを代入したいのでしょうか?
「もしNULLなら構造体の値を代入」などの処理をしたいのであれば、まずはNULLのポインタに
領域を確保するか、すでに確保されているアドレスを代入することになります。
ご所望の代入方法をするためには、まず「領域の確保」が必要です。

これを踏まえて、代入と削除を書くと以下のようになるかと思います。

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

typedef struct _test_t {
int aaa;
int bbb;
} test_t;

typedef struct _globalData {
int xxx;
test_t *pTestData[256];
} globalData_t;

globalData_t globalData;

int main()
{
test_t testData1 = { 1, 1 };
test_t testData2 = { 2, 2 };

test_t testDataBuf[256];
int i;
for(i=0; i<256; i++)
globalData.pTestData[i] = &testDataBuf[i];

// 代入
*globalData.pTestData[1] = testData1;/* (1) */

// delete
globalData.pTestData[1] = NULL;

// 再代入
globalData.pTestData[1] = &testDataBuf[1]; // NULL状態を解消
*globalData.pTestData[1] = testData1;
}


しかし、これは無駄な処理に見えます。
このコードを読んだ人は「なぜDeleteがNULL代入なのだろうか?」と疑問に思うかもしれません。


私ならば・・・

案1
aaaが-1なら未使用というルールにして
#define delete_test_t(x) (x.aaa = -1)
#define is_enable(x) (x.aaa != -1)
とかで管理しといて、あとでソース読むのが楽になるようにケアすると思います。

案2
DeleteでNull代入する代わりにtest_t構造体に使用中フラグを追加


alloc禁止の前提ではこんなところですかね。

> 代入、*globalData.pTestData[xxx] = testData1;
> 削除 *globalData.pTestData[xxx] = NULL;

削除時点でヌルポインタになってしまうので、ご所望の書き方では削除後に代入はできません。
ちなみに削除はアスタリスクを取って
globalData.pTestData[xxx] = NULL;
が正しいと思います。

なぜNULLを代入したいのでしょうか?
「もしNULLなら構造体の値を代入」などの処理をしたいのであれば、まずはNULLのポインタに
領域を確保するか、すでに確保されているアドレスを代入することになります。
ご所望の代入方...続きを読む

Qtypedef struct OBJECT NODE; の意味を教えてください。

C言語において、

typedef struct OBJECT NODE;

に、コメント文を付けるとしたらどのようになりますか??
よろしくお願いします。

Aベストアンサー

意味は「これから NODE って出てきたら struct OBJECT と同じことだからね」ということです。

コメントに関してですが、言語に親しんだ人であれば難なく理解できる個所にはコメントを書かないのが良いマナーであると思います。
過剰なコメントは可読性を損ねますから。

この場合はコメントをつけないのが正解だと思いますよ。

Q派生クラスのメンバを基底クラスの参照に代入(C++

文末のコードのように、
基底クラスで、派生クラスのメンバの参照を持つのはまずいでしょうか。
(classではなくstructにしているのは質問上でのpublic:の省略のためだけです)

初期化順序的には、基底クラスの参照先は、
基底クラスのコンストラクタが走る時点で初期化されていないので、
コンストラクタ内で参照に対して何かしようとすると問題になると思っています。

基底クラスのコンストラクタ内で派生クラスメンバの参照に対して何かしなければ、
参照は有効で、派生クラスのコンストラクタ実行後であれば
問題なく動くと思ってよいでしょうか。

struct A {

int& m_ref;

A(int& ref) : m_ref(ref) { }

};

struct B : public A {

int m_obj;

B() : A(m_obj) { }

};

Aベストアンサー

継承は、子が親を知っている状態です。
お話しされているクラスは、親が子を知っている状態で、関係が反転しています。
これは非常に難解な状況で、子の処理結果を親が受け取りたいということなら、
テンプレートメソッドなどで対応するべきです。

Qtry{}catch(){}とデストラクタの関係を教えてください。

try-catchでメモリ確保を含むクラスをスローした場合、デストラクタはどの時点で働くのか、教えてください。たとえば、↓の使いかたは大丈夫でしょうか?

【1】
try{
 throw(CError(100, "エラー情報"));
}catch(CError& err){
 //ここでerrを参照しても問題ないのでしょうか?
}

【2】
try{
 CError err(100, "エラー情報");
 throw(err); // (1)
}catch(CError& err){
 //ここでerrを参照しても問題ないのでしょうか?
 //まだデストラクタはちゃんと動作するのでしょうか?
 //catchが呼び出し元のメンバであったりしても大丈夫なのでしょうか?
}

宜しくお願いします。

Aベストアンサー

【1】【2】どちらの場合も問題がありません。
コンパイラが必要に応じてerrオブジェクトのコピーを作成します。
デストラクタが呼び出されるタイミングはコンパイラに依存するところもあると思いますが、
例えばVC7.1では【2】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) CErrorクラスのテンポラリオブジェクト(以下a)のコピーコンストラクタが呼び出される。
(3) errオブジェクトのデストラクタが呼び出される
(4) catch文まで到達
(5) aオブジェクトのデストラクタが呼び出される。

VC7.1では、【1】は以下のように動作します。
(1) errオブジェクトのコンストラクタが呼び出される
(2) catch文まで到達
(3) errオブジェクトのデストラクタが呼び出される。

コンパイラがオブジェクトのコピーを省略しているようです。

Q構造体メンバへの代入

とても初歩的なことなのですが、
typedef struct _X{
int x;
}X[50];
と構造体を定義して
X[0].x = 0;
と0を代入しようとすると、「宣言が正しく終了していない」とエラーが出てしまいます。
これはなぜでしょうか?
ちなみにMicrosoft Visual C++ 2005 Express Editionを使っています。

Aベストアンサー

> typedef struct _X{
> int x;
> }X[50];

これは、目的と違った宣言になっています。
回答の2,3の方の言うとおりです。

typedefを使いたいのであれば、
typedef struct {
int x;
} INTX;
INTX X[50];
代入は、 X[0].x=0; と記述してもOKです。

typedefは、新しい型を宣言する場合に使います。
ここでは、INTXという新しい型を宣言しています。

typedefを使わない方法なら
struct {
int x;
} X[50];

これで、X[0].x=0; と記述できます。

ここでは、構造体に名前をつけていませんが、つけることもできます。
struct IX {
int x;
} X[50];

これは、
struct IX {
int x;
};
struct IX X[50];
とするのと同義です。

QC言語のプログラムで#includeを使わず#includeだけで

C言語のプログラムで#include<math.h>を使わず#include<stdio.h>だけで√(sqrt)を表現することは可能でしょうか?

Aベストアンサー

ご自分で sqrt 関数を作れば可能です。
こんな感じでしょうか。

#include <stdio.h>

static double
sqrt (double s)
{
 double x = s / 2.0;
 double last_x = 0.0;

 while (x != last_x)
 {
  last_x = x;
  x = (x + s / x) / 2.0;
 }

 return (x);
}

int
main (int argc, char * argv[])
{
 printf ("sqrt (%f) = %f\n", 3.0, sqrt (3.0));
}

Q構造体メンバがポインタであるときの代入

typedef struct WRITE_BUF_TYPE{
 byte adr_h; // ワードアドレス上位
 byte adr_l; // ワードアドレス下位
 byte *buf_adr; // 送信/受信先 アドレス
 byte cnt; // 文字数
};

struct W_BUF_TYPE b[10];

構造体、データ定義を上のようにしています。
b[10]の空きを探して書き込むサブルーチンを作ったのですが、*buf_adrの設定方法がわかりません。
ご存知の方、教えてください。

サブルーチン
sub_func(int8 *adr){
 byte i;
 for(i=0;i<10;i++){
   if(b[i].adr_h==0){  // b[10]の空き検索
   b[i].buf_adr=*adr; // アドレスを設定する。ここでエラーとなります。
 }
}
サブルーチンでバッファのアドレスを受けて、b[10]の空きエリアに設定するプログラムです。

Aベストアンサー

b[i].buf_adr=*adr; → b[i].buf_adr=adr;
ポインタ同士なのだから、そのまま転記する。
最初の書き方だと、ポインタ←ポインタの指している内容(整数)を
行うと言う意味なので、エラーになる。
別に左辺が構造体のメンバでなくても間違いです。

Qchar AA[]{"全角文字"};から"全"という一字を取り出したい

 今晩は、Cの初心者です、宜しくお願いします。
 全角文字の入ったchar AA[]{"全角文字"};から"全"という文字一字を取り出す時にAA[0]とかくとエラーになります。
 どのようにしたら取り出せるのでしょう。
 ポインタを使う方法と使わない方法を教えて下さい。
 宜しくお願いします。

Aベストアンサー

お疲れ様です。

まずお伺いしたのがOSおよび開発するためのコンパイラです。

ロケール等の話は分かりませんが、昔のC言語で日本語を扱う場合には全角文字1文字で2個つのchar領域を使用していました。
(マルチバイト文字セットと言います。)

詳細は参考URLを参照の事。

windowsでVCと仮定した場合、charを使われていると言うことは、多分、shift-jis(シフトJIS)で文字列を扱っていると思われます。

結論として全角文字1文字だけを取り出したいという場合は、結局char2個分のデータを取り出す必要があります。

>char AA[]={'全','角'};

char AA[]="全角";
とし
>printf("%s%s\n" , AA[0],AA[1] ) ;

printf("%c%c\n" , AA[0],AA[1] ) ;
とすれば、「全」だけを表示する事が可能と思われます。

日本語を文字列で表示する為の文字コードについては
Shift-JISだけでなく、UnicodeやUTF・EUC・JISなどがあります。

もう少し詳しく記載してあるホームページはないか探してみましたが、ちょっと無理でした。

参考URL:http://marupeke296.com/CPP_charUnicodeWideChar.html

お疲れ様です。

まずお伺いしたのがOSおよび開発するためのコンパイラです。

ロケール等の話は分かりませんが、昔のC言語で日本語を扱う場合には全角文字1文字で2個つのchar領域を使用していました。
(マルチバイト文字セットと言います。)

詳細は参考URLを参照の事。

windowsでVCと仮定した場合、charを使われていると言うことは、多分、shift-jis(シフトJIS)で文字列を扱っていると思われます。

結論として全角文字1文字だけを取り出したいという場合は、結局char2個分のデータを取り出...続きを読む


人気Q&Aランキング