二次元配列の範囲外アクセスができません。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
soodbt

二次元配列の範囲外アクセスができません。

#1

投稿記事 by soodbt » 14年前

見下ろし型の全方位シューティングを作っているのですが
画面の大きさの二次元配列の
field[-640][-480]~field[1280][960]に0を
field[0][0]field[640][480]にすべて1を
代入して例えば

コード:

int field_check(int x,int y){
if(y<-640||1280<y||x<-480||960<x){
return-1;
}else{
return field[x][y];
}
}
そこで、予め他にint型の
field_tmp[640*3][480*3]を宣言しておき
field_tmp[640][480]のアドレスに
field[0][0]を持ってくればいいと考えました。
しかしうまくいかず、コンパイラは通りますがいざ起動すると強制終了します。
どうしたらいいでしょうか?
マルチポストしていたので気分を害される方もいるかもしれませんが
よろしくお願いします。

↓マルチポストしていた文章です。

.h
int field_tmp[Y_MAX][X_MAX];
extern int **field=(int**)&(field_tmp[Y_MAX][X_MAX]);

↑複数のファイルでインクルードしてるため再定義エラーになる。

.h
int field_tmp[Y_MAX][X_MAX];
extern int **field;

ini.cpp
**field=(int**)&(field_tmp[Y_MAX][X_MAX]);

↑int **からintに変換できませんって言われる。
左辺がint**で右辺がintって言ってるんだよね?

左辺をキャストしたらアクセス違反ゆわれた(;_;)

誰かヘルプミー(;_;)

soodbt

Re: 二次元配列の範囲外アクセスができません。

#2

投稿記事 by soodbt » 14年前

すいません、Codeから下の文章が抜けました。


~~~
のように使いたいと思いました。
しかし、添字にマイナスを使うとコンパイラが想定していないところにアクセスするので
アクセス違反になります。
~~~
そこで、

アバター
bitter_fox
記事: 607
登録日時: 15年前
住所: 大阪府

Re: 二次元配列の範囲外アクセスができません。

#3

投稿記事 by bitter_fox » 14年前

soodbt さんが書きました: しかしうまくいかず、コンパイラは通りますがいざ起動すると強制終了します。
どうしたらいいでしょうか?
情報が少ないので問題点を断定できません。
現在のソースコードを教えてもらえますか?
soodbt さんが書きました: マルチポストしていたので気分を害される方もいるかもしれませんが
よろしくお願いします。

↓マルチポストしていた文章です。
文章を載せるのではなく相互リンクしてください。
詳しくはフォーラムルールを参照してください。

かずま

Re: 二次元配列の範囲外アクセスができません。

#4

投稿記事 by かずま » 14年前

soodbt さんが書きました: そこで、予め他にint型の
field_tmp[640*3][480*3]を宣言しておき
field_tmp[640][480]のアドレスに
field[0][0]を持ってくればいいと考えました。
「field[-640][-480]~field[1280][960]に0を」代入するんだったら
int field_tmp[640*3+1][480*3+1]; と宣言しないといけません。
また、field は int (*)[480*3+1] という型でないといけません。

field.h

コード:

#define X_MAX  2    // 480
#define Y_MAX  3    // 640

#define field ((int (*)[X_MAX * 3 + 1])&field_tmp[Y_MAX][X_MAX])

extern int field_tmp[Y_MAX * 3 + 1][X_MAX * 3 + 1];
ini.cpp

コード:

#include "field.h"

int field_tmp[Y_MAX * 3 + 1][X_MAX * 3 + 1];

void init_field()
{
    for (int y = 0; y <= Y_MAX; y++)
        for (int x = 0; x <= X_MAX; x++)
            field[y][x] = 1;
}

int field_check(int x, int y)
{
    if (y < -Y_MAX || y > Y_MAX * 2 || x < - X_MAX || x > X_MAX * 2)
        return -1;
    return field[x][y];
}

#define TEST 1
#if TEST

#include <iostream>
#include <iomanip>
using namespace std;

void print()
{
    cout << "     ";
    for (int x = -X_MAX; x <= X_MAX * 2; x++)
        cout << setw(4) << x;
    cout << endl;
    for (int y = -Y_MAX; y <= Y_MAX * 2; y++) {
        cout << setw(4) << y << ':';
        for (int x = -X_MAX; x <= X_MAX * 2; x++)
            cout << setw(4) << field[y][x];
        cout << endl;
    }
    cout << endl;
}

int main()
{
    print();
    init_field();
    print();
}
#endif

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: 二次元配列の範囲外アクセスができません。

#5

投稿記事 by h2so5 » 14年前

soodbt さんが書きました: そこで、予め他にint型の
field_tmp[640*3][480*3]を宣言しておき
field_tmp[640][480]のアドレスに
field[0][0]を持ってくればいいと考えました。
そんな変なことをしなくても、
配列にアクセスするときに座標値にそれぞれ640と480を加算すれば済む話だと思いますよ。

アバター
LisetteLander
記事: 147
登録日時: 14年前
住所: 東京

Re: 二次元配列の範囲外アクセスができません。

#6

投稿記事 by LisetteLander » 14年前

h2so5 さんが書きました: そんな変なことをしなくても、
配列にアクセスするときに座標値にそれぞれ640と480を加算すれば済む話だと思いますよ。
やっぱめんどくさいって感じますよね・・・
それをやろうと思ったのはこれを理解することによってアドレスやポインタ、配列について少し学べるかなと思ったからです。

ぶっちゃけ表記の通り動かすには関数側で許容外のマイナスの値や巨大な値ををはじけばいいんですけど・・

アバター
LisetteLander
記事: 147
登録日時: 14年前
住所: 東京

Re: 二次元配列の範囲外アクセスができません。

#7

投稿記事 by LisetteLander » 14年前

bitter_fox さんが書きました: 文章を載せるのではなく相互リンクしてください。
詳しくはフォーラムルールを参照してください。
掲示板で質問し、DAT落ちしましたので行方不明です・・・

アバター
LisetteLander
記事: 147
登録日時: 14年前
住所: 東京

Re: 二次元配列の範囲外アクセスができません。

#8

投稿記事 by LisetteLander » 14年前

>かずま様
解答ありがとうございます。
配列の宣言数と、記載してくださったコードでなんとかできました!!

ありがとうございます!!!

閉鎖

“C言語何でも質問掲示板” へ戻る