Problems converting tga files to black and white - c

I have been trying to make this program to convert a tga image for color into black and white. But i have no clue how to go about it. I am verry new to C and have yet to get the hang of the syntax and even proper usage of ubuntu.
I think my problem is somthing with tha tga files header cant be read. Because the result i get when trying this program on a tga file is an unopenable picture with no height. "height = 0".
Is there some good links for one to read up on C?
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct pixel {
uint8_t r, g, b, a;
};
static uint8_t *load_image(char *filename, int *sizex, int *sizey)
{
uint8_t *image;
char buf[512];
char *bufptr;
int ret;
FILE *fp = fopen(filename, "r");
bufptr = fgets(buf, 512, fp);
ret = fscanf(fp, "%d %d\n", sizex, sizey);
bufptr = fgets(buf, 512, fp);
image = malloc(*sizex * *sizey * 4);
int i;
uint8_t *ptr = image;
for (i=0; i<*sizex * *sizey; ++i) {
ret = fread(ptr, 1, 3, fp);
ptr += 4;
}
fclose(fp);
return image;
}
static int save_image(const char *filename, uint8_t *image, int sizex, int sizey)
{
FILE *fp = fopen(filename, "w");
fprintf(fp, "P6\n%d %d\n255\n", sizex, sizey);
int i;
uint8_t *ptr = image;
for (i=0; i<sizex * sizey; ++i) {
fwrite(ptr, 1, 3, fp);
ptr += 4;
}
fclose(fp);
return 1;
}
void convert_grayscale(uint8_t *input, uint8_t *output, int sizex, int sizey)
{
// Y = 0.299 * R + 0.587 * G + 0.114 * B
int i;
for (i = 0; i < sizex * sizey; ++i)
{
struct pixel *pin = (struct pixel*) &input[i*4];
struct pixel *pout = (struct pixel*) &output[i*4];
float luma = 0.299 * pin->r + 0.587 * pin->g + 0.114 * pin->b;
if (luma > 255)
luma = 255;
uint8_t intluma = (int) luma;
pout->r = intluma;
pout->g = intluma;
pout->b = intluma;
pout->a = 255;
}
}
int main()
{
uint8_t *inputimg, *outputimg;
int sizex, sizey;
inputimg = load_image("image.tga", &sizex, &sizey);
outputimg = malloc(sizex * sizey * 4);
convert_grayscale(inputimg, outputimg, sizex, sizey);
save_image("output.tga", outputimg, sizex, sizey);
}

(Personal note: A longer answer after reading Why Stackoverflow sucks. That should be Required Reading for everyone who gets Moderator privileges.)
The problem is your load_image code seems designed to read PPM (ASCII-based) images:
Each PPM image consists of the following:
1. A "magic number" for identifying the file type. A ppm image's magic number is the two characters "P6".
2. Whitespace (blanks, TABs, CRs, LFs).
3. A width, formatted as ASCII characters in decimal.
4. Whitespace.
5. A height, again in ASCII decimal.
6. Whitespace.
7. The maximum color value (Maxval), again in ASCII decimal. Must be less than 65536 and more than zero.
8. A single whitespace character (usually a newline).
9. A raster of Height rows [...]
-- your first fgets reads, then discards, the "magic number" line, followed by reading the width and height, and then discarding the "maxval" line.
It ought to work for PPM images (and you could rename this routine load_ppm_image) were it not for a single important issue: after all that ASCII stuff, you switch to fread, and so here is Warning #1.
Before opening your file, decide whether you are going to read exclusively ASCII text, or might need to read binary data.
The problem is that 'text mode' "w" converts certain characters when reading and writing into others. That's built-in behavior in all common C libraries; it attempts to fix the end-of-line characters mess that a previous generation of programmers left us with. Now, reading text files in text mode got a bit simpler, but reading binary data is impossible. You can't be sure you got exactly what was in the file.
Let's get on with Warning #2: not all file formats are the same.
The above routine works (mostly) for PPM images, but it will fail on TGA because its header is organized differently. The TGA header is described rather well here (a random pick of Google results).
The specification describes bytes, so first thing to do is change your fopen line to
FILE *fp = fopen(filename, "rb");
and, by the way, a good practice is to test if it was successful:
if (fp == NULL)
{
printf ("Opening the file '%s' failed\n", filename);
return NULL;
}
Then you can use fgetc or fread to read one or more bytes. Here comes Warning #3: use fread with care.
fread reads multiple bytes in the order in which they are stored into the file, and so you would think it may read an item such as width and height -- each a 2-byte integer value -- in one 'read' operation. But fread does not know the order of the bytes in your system (nor in the file itself), and so it could be it reads "lo-hi", as in the specification I pointed to, while in your computer the order of bytes in an integer is "hi-lo". To clarify: if the file contains this
80 00
and you read, then store, this with fread (&width,1,2, fp), these 2 bytes get stored into computer memory in that same order. The bytes are in Big-Endian order; the "large" byte is at the end. But if your computer happens to be a Little-Endian order system, you would not get the value 0x0080 = 128 but 0x8000 = 32768 instead!
The way to circumvent this is to read one byte at a time:
width = fgetc(fp) + (fgetc(fp)<<8);
will always read the data in the correct order: low first, then high. Only the sum gets stored (in the order for your system, but that's now irrelevant!).
With the above, I think I'm out of warnings. Using the TGA specifications as a guide, you can now open the file, read the header one byte at a time until you have all information that's needed, and continue to fread your raw image data into memory. You can safely use fread to read your image bytes three at a time because they will appear in the same order into memory as they were read (they are not integers or larger, so the "memory order" is not an issue).
A good approach to ensure you are reading the correct information is this:
Read one byte at a time, to prevent endianness issues.
Add a comment in your code detailing what it is
Print out the value
Check with the specifications if the value is allowed.
To get you started, after the fopen line (and the required check if it worked):
int idLength = fgetc(fp); /* length of id string after header */
printf ("id length: %u bytes\n", idLength);
int colorMapType = fgetc(fp); /* 0 = RGB */
printf ("color map type: %u\n", colorMapType);
if (colorMapType != 0)
{
printf ("unexpected color map type!\n");
return NULL;
}
int imageType = fgetc(fp); /* 0 = None, 1 = Indexed, 2 = RGB, 3 = Greyscale */
.. and so on. When the entire header has been read and you didn't encounter surprises, you are ready to set up things to read the actual image data. No changes needed there, your existing code should work just fine.
Post-edit: I see I used
int colorMapType = fgetc(fp);
where the 'color map type' is in fact a byte, not an integer. That is to allow a belt-and-suspenders approach. If you encounter the end of the file while you are reading the header, the code that fgetc returns is EOF. EOF cannot be stored into a char, because it is an integer value: 0xFFFFFFFF (more accurately: (int)-1). If you store it into a char, you cannot distinguish it from the perfectly okay value 0x000000FF (the value 255).
The belt-and-suspender approach is to check each and every single byte:
if (colorMapType == EOF)
{
printf ("encountered unexpected end of file!\n");
return NULL;
}
Overkill if you are working with a known file, and you know it's a valid TGA (you can view and edit it with bitmap editors), but if you ever plan to work on files of which you don't know if they are valid, you might need this.

Related

How does fread deal with trailing garbage when reaching the end of the file?

I recently started dabbing in C again, a language I'm not particularly proficient at and, in fact, keep forgetting (I mostly code in Python). My idea here is to read data from a hypothetically large file as chunks and then process the data accordingly. For now, I'm simulating this by actually loading the whole file into a buffer of type short with fread. This method will be changed, since it would be a very bad idea for, say, a file that's 1 GB, I'd think. The end goal is to read a chunk as one, process, move the cursor, read another chunk and so on.
The file in question is 43 bytes and has the phrase "The quick brown fox jumps over the lazy dog". This size is convenient because it's a prime number, so no matter how many bytes I split it into, there will always be trailing garbage (due to the buffer having leftover space?). Data processing in this case is just printing out the shorts as two chars after byte manipulation (see code below)
#include <stdio.h>
#include <stdlib.h>
#define MAX_BUFF_SIZE 1024
long file_size(FILE *f)
{
if (fseek(f, 0, SEEK_END) != 0) exit(EXIT_FAILURE); // Move cursor to the end
long file_size = ftell(f); // Determine position to get file size
rewind(f);
return file_size;
}
int main(int argc, char* argv[])
{
short buff[MAX_BUFF_SIZE] = {0}; // Initialize to 0 remove trailing garbage
char* filename = argv[1];
FILE* fp = fopen(filename, "r");
if (fp)
{
size_t size = sizeof(buff[0]); // Size in bytes of each chunk. Fixed to 2 bytes
int nmemb = (file_size(fp) + size - 1) / size; // Number of chunks to read from file
// (ceil f_size/size)
printf("Should read at most %d chunks\n", nmemb);
short mask = 0xFF; // Mask to take first or second byte
size_t num_read = fread(buff, size, nmemb, fp);
printf("Read %lu chunks\n\n", num_read); // Seems to have read more? Look into.
for (int i=0; i<nmemb; i++) {
char first_byte = buff[i] & mask;
char second_byte = (buff[i] >> 8) & mask; // Identity for 2 bytes. Keep mask for consistency
printf("Chunk %02d: 0x%04x | %c %c\n", // Remember little endian (bytes reversed)
i, buff[i], first_byte, second_byte);
}
fclose(fp);
} else
{
printf("File %s not found\n", filename);
return 1;
}
return 0;
}
Now yesterday, on printing out the last chunk of data I was getting "Chunk 21: 0xffff9567 | g". The last (first?) byte (0x67) is g, and I did expect some trailing garbage, but I don't understand why it was printing out so many bytes when the variable buff has shorts in it. At that point I was just printing the hex as %x, not %04x, and buff was not initialized to 0. Today, I decided to initialize it to 0 and not only did the garbage disappear, but I can't recreate the problem even after leaving buff uninitialized again.
So here are my questions that hopefully aren't too abstract:
Does fread look beyond the file when reading data and does it remove trailing garbage itself, or is it up to us?
Why was printf showing an int when the buffer is a short? (I assume %x is for ints) and why can't I replicate the behaviour even after leaving buff without initialization?
Should I always initialize the buffer to zero to remove trailing garbage? What's the usual approach here?
I hope these aren't too many, or too vague, questions, and that I was clear enough. Like I said, I don't know much about C but find low-mid level programming very interesting, especially when it comes to direct data bit/byte manipulation.
Hope you have a great day!
EDIT 1:
Some of you wisely suggested I use num_read instead of nmemb on the loop, since that's the return value of fread, but that means I'll discard the rest of the file (nmemb is 22 but num_read is 21). Is that the usual approach? Also, thank you for pointing out that %x was casting to unsigned int, hence the 4 bytes instead of 2.
EDIT 2:
For clarification, and since I mispoke in a comment, I'd like to keep the remaining byte (or data), while discarding the rest, which is undefined. I don't know if this is the usual approach since if I use num_read in the loop, whatever is leftover at the end is discarded, data or not. I'm more interested in knowing what the usual approach is: discard leftover data or remove anything that we know is undefined, in this case one of the bytes.

Not detecting EOF

I hope this is not a turkey of a question. My conditional to detect EOF does not seem to work. The code continues through the EOF and processes within the statement. When I recreate the text, it appears appropriately, however the entire bmp with garbage code also prints out telling me the end of text flag never was encoded. I have placed a printf statement in the next else conditional, however it never enters that to print. I can not see what the problem is, if it is right in front of me, or something more ominous. Thanks as always!
/*******************************************************************************
* This code is to take a text document and using steganography techniques, hide
* the text within a bmp. It will take each character of the text, parse it into
* four 2 bit pieces and inject those bits into the two least significant bits
* of each pixel color (BGR) byte as well as the line padding.
******************************************************************************/
#include <stdio.h>
/*******************************************************************************
* getIntFromArray (borrowed from class notes). Takes unsigned character array
* and assembles/returns an int value using bit shifting with OR.
******************************************************************************/
int getIntFromArray(unsigned char bytes[])
{
int n =
bytes[0] |
bytes[1] << 8 |
bytes[2] << 16 |
bytes[3] << 24;
return n;
}
/*******************************************************************************
* bitWise. Take unsigned char pointer and character, parses the character
* using bitwise manipulation and injects 2 bits into the 2 least significant
* bits of each pixel color byte as well as padding.
******************************************************************************/
void bitWise(unsigned char* bytes, char character)
{
int i;
char tmpChar;
for(i = 0; i < 4; ++i)
{
tmpChar = character;
tmpChar &= 3;
bytes[i] &= 252;
bytes[i] |= tmpChar;
character = character >> 2;
}
}
int flag = 0;
int main(int argc, char **argv)
{
char *infilename = argv[1];
char *outfilename = argv[2];
unsigned char header[54];
FILE *in = fopen(infilename, "rb");/*Command line input.*/
FILE *out = fopen(outfilename, "wb");/*Command line input.*/
int pixelWidth;
int pixelHeight;
int i;
int j;
fread(header, 1, 54, in);/* read header into array */
pixelWidth = getIntFromArray(&header[18]);
pixelHeight = getIntFromArray(&header[22]);
fwrite(header, 1, sizeof(header), out);/* write header to output file */
for(i = 0; i < pixelHeight; ++i)/*Loop to read pixel data from bmp.*/
{
for(j = 0; j < pixelWidth; ++j)
{
unsigned char bytes[4];
unsigned char character = 0;
fread(&bytes, 1, 4, in);/*Reads sequentially pixel and padding bytes.*/
if(flag == 0)/*Breakout flag, initially set to 0.*/
{
character = getchar();/*Takes in characters from stdin.*/
if(character != EOF)/*Breakout if EOF.*/
{
bitWise(bytes, character);
}
else
{
bitWise(bytes, 0);/*Sets end of hidden text with 4 bytes LSB to 0.*/
flag = 1;
}
}
fwrite(&bytes, 1, 4, out);
}
}
fclose(in);
fclose(out);
return 0;
}
You are assigning signed int to an unsigned int. The result will be not what you expect it to be. It will be a value with all bits set to 1. (EOF has value -1 so it is signed).
Long story short it should be int. Simple int character would serves the purpose.
Also another thing getchar() returns int.
int getchar(void);
There are few other things to do :-
fread return value should be checked.
size_t fread(void * restrict ptr,size_t size, size_t nmemb,FILE * restrict stream);
The fread function returns the number of elements successfully
read, which may be less than nmemb if a read error or end-of-file
is encountered. If size or nmemb is zero, fread returns zero and
the contents of the array and the state of the stream
remain unchanged
Another thing is to check the return value of fopen(). In case of failure the return value would be NULL.
There are two serious but common problems here which lead me to believe you're not reading a reputable book, or you're having serious problems with it, as the reputable book would cover those problems in early chapters.
Perhaps we should look at some other options, since whatever you're using now clearly isn't working for you. You could've been reading your book all of this time you were struggling with trial and error, and your book should have guided you nicely past these common issues.
The bottom line is: you need to respect return values.
Don't try to convert return values before you check them. In unsigned char character; character = getchar(); you're converting from what the books and getchar manual says is an int to an unsigned char, before you try to check it against EOF. That conversion may result in loss of data. Do you wonder which data you've lost?
If you're struggling to understand K&R2E or a manual, you should write a question about that which you don't understand, rather than moving on, confused, to write code which relies upon guesswork. Any guesswork is dangerous in languages such as C.
You should also check the return value of fread, and I'd expect to see the size parameter passed 54 and the count parameter passed 1 in your case. That way, you can treat occasions when fread only reads fifty-three bytes (or fifty-two, or fifty-one) as though it's the end of input, rather than treating that unexpectedly short input as though it's the expected size. Like the getchar manual, you can find out all about fread from the fread manual.
Ohh, and nowadays I get a whole lot of "but the Youtube videos" responses. Youtube isn't a good substitute for a reputable book. Anybody can jump on there and "just wing it", and the video you watch will likely be equally flawed as your own guesses. A reputable book, on the other hand, has had thousands of hours put into planning, peer reviewing, testing (on students, since these books are usually written by professors who also have classes to teach) and refactoring (based on the testing, to better deal with "hiccups" that occur).
The choice should be obvious, and the proof is in the eating of the pudding. If you've tried the "youtube" or "try it and see" methods, they're not working for you; what you see before you now is the result of that. Try something else. Good luck!

Using information from an external file, How can I fill my array up correctly using fread?

I need to be able to make sure my array is correctly receiving values from the file card.raw through fread.
I am not confident about using arrays with pointers, so if anybody could help me with the theory here, it would be GREATLY appreciate it. Thanks in advance.
The code is supposed to take literally one block of size 512 bytes and stick it into the array. Then I am just using a debugger and printf to examine the arrays output.
/**
* recover.c
*
* Computer Science 50
* Problem Set 4
*
* Recovers JPEGs from a forensic image.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(int argc, char* argv[])
{
//Size of EACH FAT JPEG in bytes
#define FILESIZE 512
unsigned char* buffer[FILESIZE];
///Step 1: Open jpeg
FILE* readfrom = fopen("card.raw", "rb");
if (readfrom == NULL)
{
printf("Could not open");
}
///Step 2: Find Beginning of JPEG. The first digits will be 255216255 Then 224 or 225
fread(&buffer, FILESIZE, 1, readfrom);
for(int x = 0; x < FILESIZE; x++)
{
printf("%d = %c\n", x, buffer[x]);
}
fclose(readfrom);
}
Use return values from input functions. fread() reports how many elements were read - code might not have read 512. Swap FILESIZE, 1 to detect the number of characters/bytes read.
// fread(&buffer, FILESIZE, 1, readfrom);
size_t count = fread(&buffer, 1, FILESIZE, readfrom);
Only print out up to the number of elements read. Recommend hexadecimal (and maybe decimal) output rather than character.
for(size_t x = 0; x < count; x++) {
// printf("%d = %c\n", x, buffer[x]);
printf("%3zu = %02X % 3u\n", x, buffer[x], buffer[x]);
}
If the fopen() failed, best to not continue with for() and fclose().
if (readfrom == NULL) {
printf("Could not open");
return -1;
}
The second parameter is size, in bytes, of each element to be read.
The third parameter is Number of elements each one with a size of the <second parameter> bytes.
So, swap your second and first parameters.
Replace unsigned char* buffer[FILESIZE]; with unsigned char buffer[FILESIZE];. For now, you have an array of unsigned char *, when you need unsigned char. Because buffer is already a pointer, you don't need to take its address. In fread call, replace &buffer with buffer.
It must go like this: fread(buffer, 1, FILESIZE, readfrom);
One more thing: add return with a specific error code after printf("Could not open");, because if file hasn't been open, you cannot read from it, can you? And add return 0; in the end of main.
And take your #define out of main.
Read more about fread here: http://www.cplusplus.com/reference/cstdio/fread/

How to read a char array stored in a file, into a char buffer during runtime

I'm working in C and I'm modifying existing code.
I have a char array which is stored in a file as follows:
"\x01\x02\x03"
"\x04\x05\x06"
"\x07\x08\x09"
In the original source code this char array is included as follows:
const static char chs[] =
#include "file.h"
;
I'm modifying this code to load the file into a char array during runtime (to get the exact same result as with the above approach) instead of it to be included by the pre-processor. My first approach was to simply read the file into a char buffer, as follows:
FILE *fp;
const char *filename = "file.h";
fp = fopen (filename, "rb");
assert(fp != NULL);
fseek(fp, 0L, SEEK_END);
long int size = ftell(fp);
rewind(fp);
// read entire file into the buffer
char *buffer = (char*)malloc(sizeof(char) * size);
size_t nrOfBytesRead = fread(buffer, 1, size, fp);
However I've quickly discovered that this is not correct. The file already contains the exact code representation of the char array, I cannot simply read it into a char buffer and get the same result as the include approach.
What is the best way to get my char array which is stored in file, into a char array during runtime?
As you've seen, when you read the file using fread it reads it byte for byte. It doesn't get any of the syntactic processing that the compiler does on your source files. It doesn't know that strings live inside of quotes. It doesn't map escape sequences like \x01 into single bytes.
You have several different possibilities for fixing this:
Teach your program how to do that processing as it reads the file. This would be a fair amount of work.
Put just the bytes you want into the file.
Pick a different encoding for your file.
To say a little more about #2: If you don't want to change your file-reading code, what you can do is to create an (in this case) 9-byte file containing just the nine bytes you want. Since your nine bytes are not text, it'll end up being a "binary" file, which you won't be able to straightforwardly edit with an ordinary text editor, etc. (In fact, depending on the tools you have available to you, it might be challenging just to create this particular 9-byte file.)
So if you can't use #1 or #2, you might want to go with #3: pick a brand-new way to encode the data in the file, easier to parse than #1, but easier to prepare than #2. My first thought would be to have the file be hexadecimal. That is, the file would contain
010203040506070809
or
010203
040506
070809
Your file-reading code, instead of the single call to fread, would read two characters at a time and assemble them into bytes for your array. (I'd sketch this out for you, but the compilation I was waiting for has finished, and I ought to get back to my job.)
This should read the hex values from the file and save them to buffer.
fgets() reads each line from the file.
sscanf() reads each hex value from the line.
The format string for sscanf, "\\x%x%n", scans the backslash, an x, the hex value and stores the number of characters processed by the scan. The number of characters processed is used to advance through the line. This is needed if some lines have a different number of hex values.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char line[100] = {'\0'};
unsigned char *buffer = NULL;
unsigned char *temp = NULL;
unsigned int hex = 0;
int size = 0;
int offset = 0;
int used = 0;
int bufferused = 0;
int increment = 100;
int each = 0;
FILE *pf = NULL;
if ( ( pf = fopen ( "file.h", "r")) != NULL) {
while ( fgets ( line, sizeof ( line), pf)) {//get each line of the file
offset = 1;//to skip leading quote
//sscanf each hex value in the line
while ( ( sscanf ( line + offset, "\\x%x%n", &hex, &used)) == 1) {
offset += used;// to advance through the line
if ( bufferused >= size) {
temp = realloc ( buffer, size + increment);
if ( temp == NULL) {
//one way to handle the failure
printf ( "realloc failed\n");
free ( buffer);
exit (1);
}
buffer = temp;
size += increment;
}
buffer[bufferused] = hex;
bufferused++;
}
}
fclose ( pf);
}
for ( each = 0; each < bufferused; each++) {
printf ( "%x\n", buffer[each]);
}
free ( buffer);
return 0;
}

Segfault in fread()

I'm trying to read a BMP image (greyscales) with C, save values into an array, and convert this array to a string with values separated with a comma.
My program worked well under Windows 7 64-bit, but I had to move to Windows XP 32-bit because of library compatibility problems.
I have 1,750 images to read, and I want to store all of them in a single string.
When I launch my program it goes fine until the 509:th image, then I get a Segmentation Fault caused by fread(). Here's my code:
int i=0,j,k,num,len,length,l;
unsigned char *Buffer;
FILE *fp;
char *string,*finalstring;
char *query;
char tmp2[5],tmp[3];
query = (char *)malloc(sizeof(char)*200000000);
string = (char *)malloc(sizeof(char)*101376);
Buffer = (unsigned char *)malloc(sizeof(unsigned char)*26368);
BITMAPFILEHEADER bMapFileHeader;
BITMAPINFOHEADER bMapInfoHeader;
length = 0;
for (k =1;k<1751;k++)
{
strcpy(link,"imagepath");
//here just indexing the images from 0000 to 1750
sprintf(tmp2,"%.4d",k);
strcat(link,tmp2);
strcat(link,".bmp");
fp = fopen(link, "rb");
num = fread(&bMapFileHeader,sizeof(BITMAPFILEHEADER),1,fp);
num = fread(&bMapInfoHeader,sizeof(BITMAPINFOHEADER),1,fp);
//seek beginning of data in bitmap
fseek(fp,54,SEEK_SET);
//read in bitmap file to data
fread(Buffer,26368,1,fp);
l=0;
for(i=1024;i<26368;i++)
{
itoa(Buffer[i],tmp,10);
len = strlen(tmp);
memcpy(string+l,tmp,len);
memcpy(string+l+len,",",1);
l = l+len+1;
}
memcpy(query,"",1);
memcpy(string,"",1);
printf("%i\n",k);
}
Thanks
Make it tmp[4]; for three digits and the terminating 0.
Also: where is the fclose? I suspect that you're running out of file handles.
Check, whether fp != 0.
Where did you get 101376 from? Each of your bytes take up at most 5 characters as a decimal number with comma (e.g. -127,), 5*26368 is 131840.
Get rid of the casts in malloc calls. And #include <stdlib.h>.
What's the output of this program, in both the 64-bit and 32-bit systems you're using?
#include <stdio.h>
int main(void) {
printf("sizeof (int) is %d\n", (int)(sizeof (int)));
printf("sizeof (int*) is %d\n", (int)(sizeof (int*)));
return 0;
}
Run your program in the debugger.
Set a breakpoint at the call to
fread -- make it conditional on
k==507 (this will stop it when you
expect the fread to be successful).
When the program hits the
breakpoint, examine the variables
and check what is about to be passed
to fread. The first one or two times
you hit the breakpoint, the values
will be good.
Then on the 509th time, you will
probably see bogus values being passed
to fread. Figure out where those
bogus values are coming from --
possibly set a conditional
breakpoint on the variable being set
to whatever the bogus value is.

Resources