ポインタの中身が「CXX0030」になってしまう

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
wasawasa
記事: 94
登録日時: 11年前

ポインタの中身が「CXX0030」になってしまう

#1

投稿記事 by wasawasa » 10年前

こんにちは、何度もお世話になっております。
int型の整数とchar型ポインタポインタとint型ポインタを入力して16進数表記のchar型文字列と文字列の長さを出力するDP_intfwrite関数と、char型のstrポインタとint型のsize変数から成るDP_STR_hashcal構造体を宣言してそれらをDP_intfwrite関数に入力して出力結果をprintfで表示するmain関数を下記のように書きました。
そうしたら、DP_intfwrite関数内で16進数表記のchar型文字列をDP_STR_hashcal.strに格納する段階で書き込み違反が起きてしまいました。
デバッガでDP_STR_hashcal.strの内容を見た所、DP_intfwrite関数を呼び出す前の時点で「 = CXX0030: エラーです: 式を評価できません」という内容になっていました。
NULLを代入した後もNULLポインタにならずこの内容のままだったので定義か宣言の時点で間違っているのだと思うのですが、どこが間違っているのかが分かりません。
一体どのような間違いをしてしまっているのでしょうか?どなたかよろしくお願いします。

コード:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <commctrl.h>
#include <shlwapi.h>
#include <math.h>

#define DEF_DP_Hassh_Size					16
#define DEF_DP_Int_Size						9
#define DEF_DP_Absolute_Int_Size			8
#define DEF_DP_Int_Plus						'0'
#define DEF_DP_Int_Minus					'1'
#define DEF_DP_Int_NumBase					16
#define DEF_DP_FileSignature_Word			"|GM1"
#define DEF_DP_FileSignature_Size			4
#define DEF_DP_FileVersion_Word				"0.10"
#define DEF_DP_FileVersion_Size				4
#define DEF_DP_MaterialChunk_ChunkType_Word "/MTL"
#define DEF_DP_MaterialChunk_ChunkType_Size 4
#define DEF_DP_MaterialChunk_IntDataNum		5
#define DEF_DP_SinATileChunk_ChunkType_Word "\ATL"
#define DEF_DP_SinATileChunk_ChunkType_Size 4
#define DEF_DP_SinATileChunk_AbsIntDataNum	1
#define DEF_DP_SinATileChunk_IntDataNum		4
#define DEF_DP_SinNTileChunk_ChunkType_Word "\NTL"
#define DEF_DP_SinNTileChunk_ChunkType_Size 4
#define DEF_DP_SinNTileChunk_AbsIntDataNum	1
#define DEF_DP_SinNTileChunk_IntDataNum		4
#define DEF_DP_SinPanrmChunk_ChunkType_Word "\PNR"
#define DEF_DP_SinPanrmChunk_ChunkType_Size 4
#define DEF_DP_SinPanrmChunk_AbsIntDataNum	1
#define DEF_DP_SinPanrmChunk_IntDataNum		3
#define DEF_DP_SinFogChunk_ChunkType_Word "\FOG"
#define DEF_DP_SinFogChunk_ChunkType_Size	4
#define DEF_DP_SinFogChunk_AbsIntDataNum	1
#define DEF_DP_SinFogChunk_IntDataNum		3

char DP_DigitNumStr[DEF_DP_Int_NumBase]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

typedef struct{
	char *str;
	int size;
}DP_STR_hashcal;

int DP_intfwrite(int i_num,int i_abslt,char **i_p_writedata,int *i_p_writesize){
	int size,numbase,digitnum,roop1;
	static char writestr[DEF_DP_Int_Size];
	//+-判定
	if(i_num < 0)
		writestr[0] = DEF_DP_Int_Minus;
	else
		writestr[0] = DEF_DP_Int_Plus;
	//16進数変換
	for(roop1=DEF_DP_Int_Size-1;roop1>0;roop1--){
		numbase = (int)pow((double)DEF_DP_Int_NumBase,(double)(roop1-1));
		digitnum = (i_num/numbase)%DEF_DP_Int_NumBase;
		if(roop1==DEF_DP_Int_Size-1 && digitnum > DEF_DP_Int_NumBase-1 )
			return FALSE;
		writestr[DEF_DP_Int_Size-roop1] = DP_DigitNumStr[digitnum];
	}
	//文字列返す
	for(roop1 = i_abslt;roop1<DEF_DP_Int_Size;roop1++)
		*i_p_writedata[roop1-i_abslt] = writestr[roop1];
	//書き込み内容を返す
	if(i_abslt == TRUE)
		size = DEF_DP_Absolute_Int_Size;
	else if(i_abslt == FALSE)
		size = DEF_DP_Int_Size;
	else
		return FALSE;
	i_p_writesize = &size;

	return TRUE;
}

// メイン関数
int main( void )
{
	DP_STR_hashcal test;
	int a,b;
	int errorcheck;
	test.size = 0;
	test.str = NULL;
	while(1){
		printf("16進数に変換する10進数->");
		scanf("%d",&a);
		printf("\n");
		printf("絶対数出力の適用?(yes->1:no->0)->");
		scanf("%d",&b);
		printf("\n");
		errorcheck = DP_intfwrite(a,b,&test.str,&test.size);
		if(errorcheck==TRUE)
			printf("str:%s◆size:%d\n",test.str,test.size);
		else
			printf("error\n");
	}
    return 0;
}

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ポインタの中身が「CXX0030」になってしまう

#2

投稿記事 by みけCAT » 10年前

wasawasa さんが書きました:デバッガでDP_STR_hashcal.strの内容を見た所、DP_intfwrite関数を呼び出す前の時点で「 = CXX0030: エラーです: 式を評価できません」という内容になっていました。
NULLを代入した後もNULLポインタにならずこの内容のままだったので定義か宣言の時点で間違っているのだと思うのですが、どこが間違っているのかが分かりません。
DP_STR_hashcalは変数名ではなく型名なので、DP_STR_hashcal.strにはアクセス出来ないと思います。
wasawasa さんが書きました:一体どのような間違いをしてしまっているのでしょうか?どなたかよろしくお願いします。
とりあえずtest.strに領域が確保されていない問題と、
演算子の優先順位の影響で間違った領域にアクセスしている問題を直したところ、アクセス違反は出なくなりました。
しかし、今のところ

コード:

code_mod.cpp: In function 'int DP_intfwrite(int, int, char**, int*)':
code_mod.cpp:45:5: warning: parameter 'i_p_writesize' set but not used [-Wunused
-but-set-parameter]
 int DP_intfwrite(int i_num,int i_abslt,char **i_p_writedata,int *i_p_writesize)
{
     ^
という警告が出ている上、出力が文字化けして見えます。
【追記】デバッガで実行すると文字化けしましたが、普通に実行すると文字化けはしませんでした。

コード:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <commctrl.h>
#include <shlwapi.h>
#include <math.h>

#define DEF_DP_Hassh_Size					16
#define DEF_DP_Int_Size						9
#define DEF_DP_Absolute_Int_Size			8
#define DEF_DP_Int_Plus						'0'
#define DEF_DP_Int_Minus					'1'
#define DEF_DP_Int_NumBase					16
#define DEF_DP_FileSignature_Word			"|GM1"
#define DEF_DP_FileSignature_Size			4
#define DEF_DP_FileVersion_Word				"0.10"
#define DEF_DP_FileVersion_Size				4
#define DEF_DP_MaterialChunk_ChunkType_Word "/MTL"
#define DEF_DP_MaterialChunk_ChunkType_Size 4
#define DEF_DP_MaterialChunk_IntDataNum		5
#define DEF_DP_SinATileChunk_ChunkType_Word "\ATL"
#define DEF_DP_SinATileChunk_ChunkType_Size 4
#define DEF_DP_SinATileChunk_AbsIntDataNum	1
#define DEF_DP_SinATileChunk_IntDataNum		4
#define DEF_DP_SinNTileChunk_ChunkType_Word "\NTL"
#define DEF_DP_SinNTileChunk_ChunkType_Size 4
#define DEF_DP_SinNTileChunk_AbsIntDataNum	1
#define DEF_DP_SinNTileChunk_IntDataNum		4
#define DEF_DP_SinPanrmChunk_ChunkType_Word "\PNR"
#define DEF_DP_SinPanrmChunk_ChunkType_Size 4
#define DEF_DP_SinPanrmChunk_AbsIntDataNum	1
#define DEF_DP_SinPanrmChunk_IntDataNum		3
#define DEF_DP_SinFogChunk_ChunkType_Word "\FOG"
#define DEF_DP_SinFogChunk_ChunkType_Size	4
#define DEF_DP_SinFogChunk_AbsIntDataNum	1
#define DEF_DP_SinFogChunk_IntDataNum		3

char DP_DigitNumStr[DEF_DP_Int_NumBase]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

typedef struct{
	char *str;
	int size;
}DP_STR_hashcal;

int DP_intfwrite(int i_num,int i_abslt,char **i_p_writedata,int *i_p_writesize){
	int size,numbase,digitnum,roop1;
	static char writestr[DEF_DP_Int_Size];
	//+-判定
	if(i_num < 0)
		writestr[0] = DEF_DP_Int_Minus;
	else
		writestr[0] = DEF_DP_Int_Plus;
	//16進数変換
	for(roop1=DEF_DP_Int_Size-1;roop1>0;roop1--){
		numbase = (int)pow((double)DEF_DP_Int_NumBase,(double)(roop1-1));
		digitnum = (i_num/numbase)%DEF_DP_Int_NumBase;
		if(roop1==DEF_DP_Int_Size-1 && digitnum > DEF_DP_Int_NumBase-1 )
			return FALSE;
		writestr[DEF_DP_Int_Size-roop1] = DP_DigitNumStr[digitnum];
	}
	//文字列返す
	for(roop1 = i_abslt;roop1<DEF_DP_Int_Size;roop1++)
		// *i_p_writedata[roop1-i_abslt] = writestr[roop1];
		(*i_p_writedata)[roop1-i_abslt] = writestr[roop1];
	//書き込み内容を返す
	if(i_abslt == TRUE)
		size = DEF_DP_Absolute_Int_Size;
	else if(i_abslt == FALSE)
		size = DEF_DP_Int_Size;
	else
		return FALSE;
	i_p_writesize = &size;

	return TRUE;
}

// メイン関数
int main( void )
{
	DP_STR_hashcal test;
	int a,b;
	int errorcheck;
	test.size = 0;
	//test.str = NULL;
	test.str = new char[1024];
	while(1){
		printf("16進数に変換する10進数->");
		scanf("%d",&a);
		printf("\n");
		printf("絶対数出力の適用?(yes->1:no->0)->");
		scanf("%d",&b);
		printf("\n");
		errorcheck = DP_intfwrite(a,b,&test.str,&test.size);
		if(errorcheck==TRUE)
			printf("str:%s◆size:%d\n",test.str,test.size);
		else
			printf("error\n");
	}
	delete[] test.str;
    return 0;
}
最後に編集したユーザー みけCAT on 2014年9月25日(木) 21:49 [ 編集 2 回目 ]
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

box
記事: 2002
登録日時: 14年前

Re: ポインタの中身が「CXX0030」になってしまう

#3

投稿記事 by box » 10年前

すでに回答が出ているようですが、根本的な問題は、
構造体のメンバーに
char *型
のものがあるということではないか、と思います。
char []
(サイズは適切に決める)
でないとまずいかな?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ポインタの中身が「CXX0030」になってしまう

#4

投稿記事 by みけCAT » 10年前

・無駄にi_p_writesizeを書き換えるのをやめ、i_p_writesizeが指す先のデータを書き換えるようにする
・文字列の最後にNUL文字を格納するようにする
以上の修正を行ったところ、
INT_MAXを超えない非負整数に対して通常実行・デバッガ上での実行ともに正しい出力が得られるようになりました。

コード:

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <commctrl.h>
#include <shlwapi.h>
#include <math.h>

#define DEF_DP_Hassh_Size					16
#define DEF_DP_Int_Size						9
#define DEF_DP_Absolute_Int_Size			8
#define DEF_DP_Int_Plus						'0'
#define DEF_DP_Int_Minus					'1'
#define DEF_DP_Int_NumBase					16
#define DEF_DP_FileSignature_Word			"|GM1"
#define DEF_DP_FileSignature_Size			4
#define DEF_DP_FileVersion_Word				"0.10"
#define DEF_DP_FileVersion_Size				4
#define DEF_DP_MaterialChunk_ChunkType_Word "/MTL"
#define DEF_DP_MaterialChunk_ChunkType_Size 4
#define DEF_DP_MaterialChunk_IntDataNum		5
#define DEF_DP_SinATileChunk_ChunkType_Word "\ATL"
#define DEF_DP_SinATileChunk_ChunkType_Size 4
#define DEF_DP_SinATileChunk_AbsIntDataNum	1
#define DEF_DP_SinATileChunk_IntDataNum		4
#define DEF_DP_SinNTileChunk_ChunkType_Word "\NTL"
#define DEF_DP_SinNTileChunk_ChunkType_Size 4
#define DEF_DP_SinNTileChunk_AbsIntDataNum	1
#define DEF_DP_SinNTileChunk_IntDataNum		4
#define DEF_DP_SinPanrmChunk_ChunkType_Word "\PNR"
#define DEF_DP_SinPanrmChunk_ChunkType_Size 4
#define DEF_DP_SinPanrmChunk_AbsIntDataNum	1
#define DEF_DP_SinPanrmChunk_IntDataNum		3
#define DEF_DP_SinFogChunk_ChunkType_Word "\FOG"
#define DEF_DP_SinFogChunk_ChunkType_Size	4
#define DEF_DP_SinFogChunk_AbsIntDataNum	1
#define DEF_DP_SinFogChunk_IntDataNum		3

char DP_DigitNumStr[DEF_DP_Int_NumBase]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

typedef struct{
	char *str;
	int size;
}DP_STR_hashcal;

int DP_intfwrite(int i_num,int i_abslt,char **i_p_writedata,int *i_p_writesize){
	int size,numbase,digitnum,roop1;
	static char writestr[DEF_DP_Int_Size];
	//+-判定
	if(i_num < 0)
		writestr[0] = DEF_DP_Int_Minus;
	else
		writestr[0] = DEF_DP_Int_Plus;
	//16進数変換
	for(roop1=DEF_DP_Int_Size-1;roop1>0;roop1--){
		numbase = (int)pow((double)DEF_DP_Int_NumBase,(double)(roop1-1));
		digitnum = (i_num/numbase)%DEF_DP_Int_NumBase;
		if(roop1==DEF_DP_Int_Size-1 && digitnum > DEF_DP_Int_NumBase-1 )
			return FALSE;
		writestr[DEF_DP_Int_Size-roop1] = DP_DigitNumStr[digitnum];
	}
	//文字列返す
	for(roop1 = i_abslt;roop1<DEF_DP_Int_Size;roop1++)
		// *i_p_writedata[roop1-i_abslt] = writestr[roop1];
		(*i_p_writedata)[roop1-i_abslt] = writestr[roop1];
	(*i_p_writedata)[DEF_DP_Int_Size-i_abslt] = '\0';
	//書き込み内容を返す
	if(i_abslt == TRUE)
		size = DEF_DP_Absolute_Int_Size;
	else if(i_abslt == FALSE)
		size = DEF_DP_Int_Size;
	else
		return FALSE;
	//i_p_writesize = &size;
	*i_p_writesize = size;

	return TRUE;
}

// メイン関数
int main( void )
{
	DP_STR_hashcal test;
	int a,b;
	int errorcheck;
	test.size = 0;
	//test.str = NULL;
	test.str = new char[1024];
	while(1){
		printf("16進数に変換する10進数->");
		scanf("%d",&a);
		printf("\n");
		printf("絶対数出力の適用?(yes->1:no->0)->");
		scanf("%d",&b);
		printf("\n");
		errorcheck = DP_intfwrite(a,b,&test.str,&test.size);
		if(errorcheck==TRUE)
			printf("str:%s◆size:%d\n",test.str,test.size);
		else
			printf("error\n");
	}
	delete[] test.str;
    return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

wasawasa
記事: 94
登録日時: 11年前

Re: ポインタの中身が「CXX0030」になってしまう

#5

投稿記事 by wasawasa » 10年前

>>みけCATさん
>>boxさん
返信ありがとうございます。
こちら側の返事が遅くなってしまい申し訳ございません。

提示して頂いたソースはこちらでも無事動作を確認できました。ありがとうございます。
ポインタを括弧で括らなかったのがいけなかったのですね。

あと、文字列の容量の確保も関数の中で出来ないかと思い、86行目を消して47行目と48行目の間に下記のようなソースを挟んでデバッグしてみましたが、やはりエラーが出てしまうというのと、お二人ともmain関数で文字列の確保をする事を前提で考えているあたり、それは難しい事なのだと判断して提示して頂いたソースを使いたいと思います。

コード:

//メモリ確保
	free((*i_p_writedata));
	(*i_p_writedata) = new char[DEF_DP_Int_Size+1];
	if((*i_p_writedata) == NULL)
		return FALSE;

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: ポインタの中身が「CXX0030」になってしまう

#6

投稿記事 by みけCAT » 10年前

wasawasa さんが書きました:あと、文字列の容量の確保も関数の中で出来ないかと思い、86行目を消して47行目と48行目の間に下記のようなソースを挟んでデバッグしてみましたが、やはりエラーが出てしまうというのと、お二人ともmain関数で文字列の確保をする事を前提で考えているあたり、それは難しい事なのだと判断して提示して頂いたソースを使いたいと思います。

コード:

//メモリ確保
	free((*i_p_writedata));
	(*i_p_writedata) = new char[DEF_DP_Int_Size+1];
	if((*i_p_writedata) == NULL)
		return FALSE;
mallocまたはcallocで確保していない領域をfreeで開放しようとしてはいけません。
new char[要素数]で確保した領域はdelete[]で開放しないといけません。
もちろん、確保していない領域をdeleteやdelete[]で開放するのも駄目です。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

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