Strange error in binary files and RLE

Pages: 12
Hello!

I'm implementing the RLE algorithm applyed to a matrix. I'd like to write the encoded data inm a binary file and then read that file (just to verify the encoding and writing).
But I have a strange result. In debugging mode I found that it writes correctly the vector but when I scan the file it is read once more than needed...
here is the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include <stdio.h>
#include <stdlib.h>

void RLE_enc(int **matrix, int nr, int nc, int *&vet, int *n_vet)
{

	int j, i, count, elem;
	bool exit;

	j=i=count=0;
	*n_vet = 0;
	exit = false;
	vet = new int[1];
	elem=matrix[i][j];
	
	while (!exit)
	{
		if (matrix[i][j]==elem)
		{
			count++;
			j++;
			if (j==nc)
			{
				i++;
				if (i==nr)
				{
					exit = true;
					vet = (int*) realloc(vet, sizeof(int) * ((*n_vet)+2));
					vet[(*n_vet)]=count;
					vet[(*n_vet)+1]=elem;
					(*n_vet)+=2;
				}
				else
					j=0;
			}
		}
		else
		{
			vet = (int*) realloc(vet, sizeof(int) * ((*n_vet)+2));
			vet[(*n_vet)]=count;
			vet[(*n_vet)+1]=elem;
			elem=matrix[i][j];
			(*n_vet)+=2;
			count=0;
		}
	}

  

}


int main()
{
	int **matrix;
	FILE *fp;
	int nr = 2, nc = 3, i, j;

	matrix = new int* [nr];
	for (i = 0; i<nr; i++)
		matrix[i] = new int[nc];

	for (i = 0; i<nr; i++)
		for (j= 0; j<nc; j++)
			matrix[i][j] = i*nc + j;

	int n_vet, *vet;
	RLE_enc(matrix, nr, nc, vet, &n_vet);

	fp = fopen("prova.bin", "wb");

	for (i = 0; i<n_vet; i++)
		fwrite(&vet[i], sizeof(int), 1, fp);

	fclose(fp);

	fp = fopen("prova.bin", "rb");

	i = 0;
	while (!feof(fp))
	{
		fread(&vet[i], sizeof(int), 1, fp);
		printf("%d", vet[i]);
		i++;
	}

	fclose(fp);



	return 0;


}


the output vector should be:
1 0 1 1 1 2 1 3 1 4 1 5
but the program shows a number in addition which I didn't write...what I'm wrong??

thanks
Last edited on
I noticed that in text files I don't have the error:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
...
fp = fopen("prova.bin", "w");

for (i = 0; i<n_vet; i++)
	fprintf(fp, "%d ", vet[i]);
fclose(fp);

fp = fopen("prova.bin", "r");

int aux;
while (fscanf(fp, "%d ", &aux) != EOF)
{
	printf("%d", aux);
}

fclose(fp);


and in the file & on the screen I can read
1 0 1 1 1 2 1 3 1 4 1 5

it goes stranger and stranger...
Last edited on
From what I'm able to gather and understand, you've got an array of 12 numbers which would be 0 to 11 but your while(!feof(fp)) is reading 0 to 12.

Though I'm very much a beginner and had to spend a good while looking through this code with a debugger to understand its operation enough to get an idea, it seems to me that you're reading off the end of the array.

I could be wrong, but it's a thought at least while you wait for other responses.
thanks for the reply.
The "strange" is that while writing the file it writes the 12 numbers of the array. butwhen it reads the file if goes one integer over the EOF and returns a number I haven't written!
I'm taking a crash course in some concepts here.. But your area here:
vet[(*n_vet)]=count;
vet[(*n_vet)+1]=elem;
(*n_vet)+=2;

Lets say *n_vet = 0;
The above code is essentially accomplishing:
vet[(0)] = count; // *n_vet == 0
vet[(0 + 1)] = elem; // *n_vet == 1
(0) += 2; // *n_vet == 2

When you get to your final run through this loop, placing 1 then 5 into the array, you have:
vet[(10)] = count; // *n_vet == 10
vet[(10 + 1)] = elem; // *n_vet == 11
(10) += 2; // *n_vet == 12

So you've got an array written from 0 to 11 but n_vet leaves with a value of 12, 1 larger than your array.

This is what I'm seeing, in any case.

Edit: cleaned things up a little.
Last edited on
yes, n_vet, which is the number of items in the array, should be 12 in this case (from index 0 to index 11 of the array)
Yes, but 'while (!feof(fp))' is reading from 0 to 12; 13 locations. If you force n_vet = 11; right after you call RLE_enc(), the output is correct.
in the reading process Istore the read data into the array but it is indipendent from the previous computing. It is the same if I change the reading into:

1
2
3
4
5
6
while (!feof(fp))
{
	fread(&aux, sizeof(int), 1, fp);
	printf("%d", aux);
	i++;
}


if I change n_vet into 11 then the writing cicle:
1
2
for (i = 0; i<n_vet; i++)
	fwrite(&vet[i], sizeof(int), 1, fp);


will write only 11 items of the array into the file, not 12.
simply, the strange is in the fact that I store 12 items but I read 13 items because EOF is somehow brought one item over the last item I write..
If you write from 0 to 12 with an array that has 12 indices, you're going to go off the end of your array.

Here's a more visual example:
Array Index:--0--1--2--3--4--5--6--7--8--9-10-11-12
Stored value:[1][0][1][1][1][2][1][3][1][4][1][5]-??- // Your output
Last edited on
sorry, but in this code (the file writing):
1
2
3
4
5
6
7
8
9
10
11
for (i = 0; i<n_vet; i++) // n_vet = 12
	fwrite(&vet[i], sizeof(int), 1, fp);
/*
 i = 0 (0<12 -> write the file)
 i = 1 (1<12 -> write the file)
 i = 2 (2<12 -> write the file)
 i = 3  (3<12 -> write the file)
...
 i = 10  (10<12 -> write the file)
 i = 11  (11<12 -> write the file)
 i = 12 (12<12 FALSE -> exit the cycle) */


the array index goes from 0 to 11. when i == 12 it exits the cycle! so it writes 12 numbers, index from 0 to 11
Edit: Disregarded last entry.

The thing is, my debugger is showing that !feof is doing exactly what it should. It's running from 0 to 12.
Last edited on
It should be true if the check was at the end of the cycle (like a do ... while() ) but in the "for" case the check is at the beginning so it first check the condition. if i = 1 it exits without writing nothing!
with my compiler (VS 6.0) the reading:

1
2
3
4
5
6
while (!feof(fp))
{
	fread(&aux, sizeof(int), 1, fp);
	printf("%d", aux);
	i++;
}


is done from index i=0 to i = 13. This is the problem! in the writing I write 12 items but in the reading I find 12 items into the file! and I don't know why!
The for loop seems to be writing &vet[12] as it leaves. Because I can see &vet[i] being left with an extra value as the loop breaks.
I remember reading some articles elsewhere on the feof function behavoir. You may want to change to below and see how ?

1
2
3
4
5
while (fread(&aux, sizeof(int), 1, fp)>0)
{
	printf("%d", aux);
	i++;
}
If you refer to debug watch, it's common. infact when it exit i=12 and the variable debug watch tries to show you the cet[12]value (which doesn't exist) so it reads over the array. but into the for cycle if doesn't write the vet[12] item..
it works perfectly!...but for what stange, inhuman, nonsense reason the feof function behave in this way?? It's clearly a bug!
Last edited on
Let me clarify, it was NOT my solution. I read an article elsewhere and that author like you was tearing his hairs out on such a simple problem that in the end, he conclude feof just wasn't worth all the endless nights and propose use fread return code instead.

I also wonder why this is so. Can you access the source code for feof to take a look at it's internal implementation ?
Pages: 12