Getting a runtime error::"The instruction at 0x004010b4 referencedmemory at 0x00000000. The memory c

D

David Thompson

This is equivalent to
if ( fp = (fopen(*++argv,"rb")==NULL) )
which should have given a diagnostic, in a conforming compiler; likely
a warning, since there is a feasible (though wrong) interpretation,
but that's up to the implementor. To the OP (and others), use whatever
options tell your compiler to give all the warnings it can, unless
some of them are really silly. E.g. for (very common) gcc, -Wall gives
all warnings some experienced folks consider likely to be useful, but
not actually all; -Wextra (formerly -W) and -pedantic (with -ansi or
-std=something) gives even more. There are (many!) more specific
options detailed in the info, but start with the simple way.

if(gp=fopen(*argv[1]+".rle","wb")==NULL)

This adds two addresses instead of appending a string.

Actually, no. Adding two addresses would also be a diagnostic, and
more likely an error since there isn't a sensible (mis)interpretation.
That code actually adds a _character_ to an address. Which is also
semantically wrong, arguably even more so.
To append a string you
have to allocate the string and then write into it.

char name[strlen(argv[1])+5];
sprintf(name, "%s.rle", argv[1]);
That correction however is indeed right (but only for C99;
for C90 you need to use malloc (or equivalent)).

<snip>
 
D

David Thompson

int ch, a[MAXBUFF],o[MAXBUFF],n=0,i,k;
int *p=a,*r=a,*q=o;
while(fscanf(fp,"%.2X",&ch)==1)

I guess that should be

while ( fscanf( fp, "%2X", &ch ) == 1 )

but then 'ch' should be an unsigned int - that's what you tell
fscanf() via "%X". Of course, 'p' should then also be pointer
to unsigned int and 'a' an array of unsigned ints.
The first yes in principle, although in practice signed int will work.
The second, not really. Each *value* read into ch is in the range 0 to
255, which is guaranteed to fit in a signed int and be manipulable as
such. In fact it will fit in unsigned char (which on most is exactly 0
to 255, but on all is _at least_ that) which I would consider more
appropriate to the data.
But the main problem would appear to be that you seem to be
reading a binary file (or why open it explicitely with "rb"?)
but you are reading it as if it would contain ASCII data,
which is what fscanf() is meant for. If you want to read data
from a binary file use fread().
Well, yes and no. [f]scanf and fgets (and <gack spit> gets) are
_designed_ for text formats, but they can legally be used on binary
files/streams in C. If the binary file format contains embedded text
or text-like items, it may even be sensible, although IME it is
usually better to read a whole chunk or even all of the binary file
into a buffer and then get the text pieces from that buffer with e.g.
sscanf (%n is helpful), strtol, strchr, strspn/strcspn, memchr, etc.

getc and fgetc, however, work equally on both text and binary.
fread is often best for binary, but it also works on text where you
want a fixed amount (punched card emulation anyone?), or (more common)
all of a file small enough to fit in memory.

For the files the OP is concerned with, which are being treated as
arbitrary bytes with no expected or required format or structure,
f/getc and fread are both reasonable.

Nit: strictly it's binary versus text, not necessarily ASCII. C allows
other character sets; not only are there a boatload of charsets that
are derived from ASCII but different from it, there is one serious
charset that entirely different namely EBCDIC.

Well, to begin with you start the loop with 'q' pointing
to the last element written to (with 0), so this loop
will never be run (you would need to reset 'q' first to
point again to the start of the 'o' buffer).

But also then this again would hardly any sense since you
don't seem to grasp the difference between binary and ASCII
data (putc() is for ASCII data, but you are dealing with bi-
nary) it also fails because one of the data values in the
output array could be 0, thus making you stop prematurely -
adding a 0 at the end makes only sense when you're dealing
with strings (which can't contain any '\0'), not for other
data.
For output the case is closer. fprintf, fputs, fputc and putc, and
fwrite all work on both text and binary. The first two are designed
for text, but useful for binary in some cases. Both f/putc and fwrite
work for both perfectly well.

And all the w-variants similarly, in both directions.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,082
Messages
2,570,589
Members
47,212
Latest member
JaydenBail

Latest Threads

Top