11 March 2016 - Forum Rules

Main Menu

C program crashes without any (apparent) reason

Started by Her-Saki, February 03, 2018, 01:41:33 AM

Previous topic - Next topic


Hum, two days ago I started learning C for help out NES MSG project, but the last I made crashes exactly after 1060 successful loops.

Here is the code:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void file(void);
FILE *fp;
FILE *fp2;
FILE *fp3;
char zero[20];
int one[20];
char *ptr;
char *ptr2;
long counter = 1060; //1060 is the limit, after this crash
long buffer;
long buffer2;
long buffer3;
int offset = 0;
unsigned char byte;
long len;
char posmark[20];

void file(void)
   fp = fopen("offset.txt", "r"); // read offsets from here
   fp2 = fopen("MSG.nes", "rb"); // rom
   fp3 = fopen("FFFF.dmc", "wb"); // some dummy file for writing
   fseek(fp, 0x00, SEEK_SET); // go to beggining
   fseek(fp2, 0x00, SEEK_SET);

int main (){

    fscanf(fp, "%s", &zero); // get string offset
    buffer = strtol(zero, &ptr, 16); // turn string to hex
    fseek(fp, offset, SEEK_CUR); // step in offset file
    fscanf(fp, "%s", &zero); // get lenght
    len = strtol(zero, &ptr2, 16); // turn lenght to hex
    fseek(fp2, buffer, SEEK_SET); // go to offset in rom
    fread(&buffer2, sizeof(byte), len, fp2); // read string
    fwrite(&buffer2, sizeof(byte), len, fp3); // write string to dummy
    fwrite(posmark, sizeof(byte), 1, fp3); // write hex 0x00 to keep strings divided
    fseek(fp, offset, SEEK_CUR);} // step in offset file, loop
    return (0);

1060 is the last "readable" MTE in the list,

(list sample)

056EC2 // 1060
0A // lenght
0564A5 // 1061
0A // lenght etc

Some strange things: when I change lenght in 1060 to 09 the offset for the next MTE 1061 is completely ignored, so it repeats the contents in 1060. When I change it to 08 it reads "properly" (of course with the incorrect lenght that should be 0A), but crashes when I set counter farther than 1061. If I just leave it there the program crashes. I think "len" is interfering with the buffer that contains the offset based on my tests. But I don't find the cause despite knowing this since I can't see len copying content in buffer or whatever. Changing len to long didn't help at all.
It happens that 1060 is the beginning of the "long" strings, so there's a chance that len is not treating long duration (more than 08) correctly?
If I can't solve this I'll go back to manual-writing, well, at least this situation teached me some silly C...

Kiyoshi Aman

So...where is offset modified? It looks like you're seeking to the beginning of the file every iteration, twice. Did you perhaps intend to seek using buffer instead?


I don't use C a whole lot, but I think this is the main problem:

    long buffer2;
    fread(&buffer2, sizeof(byte), len, fp2); // read string

buffer2 is a long, but you're writing to it as a byte array. If len is more than 8, you'll corrupt memory. Is entry 1060 the first one with a length higher than 8? I can't test without your input files, but see if changing buffer2 from a long to char[1000] or something fixes the problem.

I also don't know why you're using SEEK_CUR with an offset of zero like that. It shouldn't have any effect.

This code is pretty hard to read. I know you haven't used the language much, but I'd suggest using more meaningful variable names. "buffer", "buffer2", etc., are hard to work with and cause bugs like this to creep in.


Aaand it worked. Wow.
Next time I'll change variables' names. Now that I read it, yeah, they should be less boring.
I didn't notice the long-char incompatibility, so it's better to use "buffers" (I mean where things go written) generally as char arrays?
Thanks for helping out!


Glad I could help. If you use fread(), you normally read into an array that's the same type as what you're reading, which in most cases is a sequence of chars. Many other programming languages would actually consider what you were doing a type error and refuse to compile the code, but C allows it, just for the 0.1% of the time that you actually need to do something like this. Your compiler may generate warnings for these kinds of problems, so be sure to check for those.