freeの時のエラー

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

freeの時のエラー

#1

投稿記事 by makaraito » 7年前

コード:

void Image_Input(IMG_t *img, char *filename, char *mode)
{
	char mag;
	int wid, hei, lum;
	unsigned char *pix;

	FILE *fp;

	int i, j;
	unsigned int el_n, wi;

	char str[256];

	unsigned char temp[256];
	char shift;
	int pos;

	if ((fp = fopen(filename, mode)) == NULL)
	{
		printf("Input file open error\n");
		exit(2);
	}
	
	//Input header
	fgets(str, sizeof(str), fp);
	sscanf(str, "P%d", &img->magN);
	mag = img->magN;

	i = 0;
	while (1)
	{
		fgets(str, sizeof(str), fp);
		if (str[0] == '#') continue;
		if (i == 0)
		{
			sscanf(str, "%d %d", &img->width, &img->height);
			if (mag == 1 || mag == 4)
			{
				img->luminance = 0;
				break;
			}
			i++;
		}
		else if (i == 1)
		{
			sscanf(str, "%d", &img->luminance);
			break;
		}
	}
	wid = img->width;
	hei = img->height;
	lum = img->luminance;

	//Check header
	printf("Input header\n%d\n%d %d\n%d\n\n", mag, wid, hei, lum);
	if (mag < 1 || mag>6) {
		printf("magic number error\n");
		exit(2);
	}
	if (wid <= 0 || hei <= 0) {
		printf("Input width or height error\n");
		exit(2);
	}
	if (lum < 0 || lum > 255)
	{
		printf("Input luminance error\n");
		exit(2);
	}

	el_n = wid * hei;
	if (mag == 3 || mag == 6) el_n *= 3;

	img->pixels = (unsigned char*)malloc((el_n+3) * sizeof(unsigned char));
	pix = img->pixels;

	//Input pixels
	switch (mag)
	{
	case 1:
	case 2:
	case 3:
		for (i = 0; i < el_n; i++) fscanf(fp, "%d", &pix[i]);
		break;
	case 4:
		for (i = 0; i < hei; i++)
		{
			wi = wid * i;
			fread(temp, sizeof(unsigned char), (wid + 7) / 8, fp);
			shift = 8;
			pos = 0;
			for (j = 0; j < wid; j++)
			{
				shift--;
				pix[wi + j] = (temp[pos] >> shift) & 1;
				if (shift == 0)
				{
					shift = 8;
					pos++;
				}
			}
		}
		break;
	case 5:
	case 6:
		fread(pix, sizeof(unsigned char), el_n, fp);
		break;
	default:
		break;
	}
	printf("%d\n", pix[el_n-1]);
	
	fclose(fp);
	free(pix);
}

コード:

#pragma once
typedef struct {
	char magN;
	int width;
	int height;
	int luminance;
	unsigned char *pixels;
}IMG_t;
スイッチ文はcase1にとんでます。

img->pixels = (unsigned char*)malloc((el_n+3) * sizeof(unsigned char));
ここでeln+3にするとエラーが起きず、+2、+1にするとエラーになります。
エラーメッセージは
HEAP CORRUPTION DETECTED: after Normal block (#74) at 0x0353BBD8.
CRT detected that the application wrote to memory after end of heap buffer.
で、確保した領域外に書き込んでることだと思っているのですがどこではみ出しているかわかりません。
どなたかご教授くださいませorz

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

Re: freeの時のエラー

#2

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

82行目

コード:

for (i = 0; i < el_n; i++) fscanf(fp, "%d", &pix[i]);
がいけませんね。
%dはint型のデータを読むための書式なので、unsigned charへのポインタを渡すと、型が一致せず未定義動作になります。
例として4バイトのint型のデータを1バイトのunsigned char型の領域に書き込もうとすると、3バイトはみ出すことになります。
unsigned char型のデータを読むには、(コンパイラが対応しているかわかりませんが、規格上は)書式%hhuが使えるでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

makaraito
記事: 4
登録日時: 7年前

Re: freeの時のエラー

#3

投稿記事 by makaraito » 7年前

確かに!!

書式について調べてみようと思います!
ありがとうございました!!!!orz

かずま

Re: freeの時のエラー

#4

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

makaraito さんが書きました: で、確保した領域外に書き込んでることだと思っているのですがどこではみ出しているかわかりません。
82行目を次のようにすると解決します。

コード:

        for (i = 0; i < el_n; i++) fscanf(fp, "%d", &j), pix[i] = j;
73行目は +3 も + 2 も要りません。

makaraito
記事: 4
登録日時: 7年前

Re: freeの時のエラー

#5

投稿記事 by makaraito » 7年前

なるほど!
この方法だと可読性が高くなりますね!!

処理速度と可読性といろいろ考えながら2つの方法を使用していこうと思います!

どちらの方法もうまくいきました!!
お二方ともありがとうございます!

返信

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