Weird lcc-win32 behaviour

V

vittorio

While I can compile the program below under freebsd via a simple:
gcc prog1.c -o prog1
and it runs smoothly, I'm experiencing annoying problems with lcc-win32
under windows xp pro. In fact, under wedit, I can smoothly compile the
program but when I try to execute it it ends with an "abnormal termination"
and a popup complains that:

lcc runtime
Exception 0xc0000005
segment violation
address 0x73d115ce

The weirdness is greater if you think that cutting many lines of the program
and stopping the execution imediatedly after the line
fscanf(fp,"%d%d",&R,&C);

lcc-win32 chokes on the same exception.

Please help
Vittorio

For thoes who wants to have a go here is prog1.c

/* prog1.c */
/* PROGRAMMA 1
Il file matrice.txt (presente nella cartella esame) contiene alcuni dati
cosi' organizzati:
R C
a0,0 a0,1 a0,2 a0,3 ... a0,C-1
a1,0 a1,1 a1,2 a1,3 ... a1,C-1
a2,0 a2,1 a2,2 a2,3 ... a2,C-1
.......
aR-1,0 aR-1,1............ aR-1,C-1

dove R e C indicano il numero di righe e di colonne della matrice che segue,
e l'elemento generico ai,j e' un reale.
Si chiede di scrivere un programma che:

- legga questo file, trasferendo i valori in una matrice di reali (float)
allocata dinamicamente
- allochi una seconda matrice di reali delle stesse dimensioni
- ponga nell'elemento i,,j della seconda matrice la somma di tutta la riga i
e di tutta la colonna j della prima matrice
- scriva la matrice risultante nel file destinazione.txt, in modalita'
testo, con una sola cifra decimale per ogni elemento

Al termine chiudere i file e liberare la memoria. */


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


void main(void){
int i,j;
int R,C;

/*Leggo matrice.txt,trasferendo i valori in una matrice m1 di reali
allocata dinamicamente*/
FILE *fp;
fp=fopen("matrice.txt","r");
fscanf(fp,"%d%d",&R,&C);

float **m1;
m1=(float**)malloc(sizeof(float*)*R);
for(i=0;i<R;i++)
m1=(float*)malloc(sizeof(float)*C);

for(i=0;i<R;i++)
for(j=0;j<C;j++)
fscanf(fp,"%f",&m1[j]);


for(i=0;i<R;i++){
for(j=0;j<C;j++)
printf("%6.1f",m1[j]);
printf("\n");
}


/*Alloco una seconda matrice di reali delle stesse dimensioni*/
float **m2;
m2=(float**)malloc(sizeof(float*)*R);
for(i=0;i<R;i++)
m2=(float*)malloc(sizeof(float)*C);


/*Pongo nell'elemento i,j della seconda matrice la somma di tutta la riga i
e di tutta la colonna j della prima matrice*/

/*r, e c sono 2 vettori in cui pongo la somma dellle righe e colonne */
float *r,
*c;
r=(float*)malloc(sizeof(float)*R);
c=(float*)malloc(sizeof(float)*C);

for(i=0;i<R;i++){
r=0;
for(j=0;j<C;j++)
r+=m1[j];
printf("r %8.1f \n", r);
}

for(j=0;j<C;j++){
c[j]=0;
for(i=0;i<R;i++)
c[j]+=m1[j];
printf("c %8.1f \n", c[j]);
}

for(i=0;i<R;i++)
for(j=0;j<C;j++)
m2[j]=r+c[j];


FILE *fo;
fo=fopen("destinazione.txt","w");

for(i=0;i<R;i++){
for(j=0;j<C;j++)
fprintf(fo,"%6.1f",m2[j]);
fprintf(fo,"\n");
}


/*Chiudo i file e libero la memoria*/
fclose(fp);
fclose(fo);
for(i=0;i<R;i++)
free(m1);
free(m2);
free(r);
free(c);
free(m1);
free(m2);
}
 
A

A. Sinan Unur

While I can compile the program below under freebsd via a simple:
gcc prog1.c -o prog1
and it runs smoothly, I'm experiencing annoying problems with
lcc-win32 under windows xp pro. In fact, under wedit, I can smoothly
compile the program but when I try to execute it it ends with an
"abnormal termination" and a popup complains that:

lcc runtime
Exception 0xc0000005
segment violation
address 0x73d115ce

<code snipped>

Please indent properly and consistently, and use some extra whitespace.

I see no error-checking for the fopen, fscanf, and malloc calls.

There are quite a few extra-ugly casts floating around.

I would first see what fscanf returns, and whether R and C contain what
you thought they should.

Sinan
 
A

A. Sinan Unur

Sinan,
as I said even shortening the program at the line
"fscanf(fp,"%d%d",&R,&C);" lcc-win32 compiles smoothly but don't
exewcute it giving the same lcc runtime exception.

Then please provide the shortest possible code that we can compile by
just copying and pasting, along with sample input.
By the way a lessical question: what do you exactly mean with
"...There are quite a few extra-ugly casts floating around...": what
are extra-ugly casts?

The following is an ugly cast:

#include <stdlib.h>

....

float **m1;
m1=(float**)malloc(sizeof(float*)*R);

The cast (float**) is not needed. It clutters the code, and if you ever
did forget to include stdlib.h, you would not get a warning.

From what I can surmise, the recommended replacement for the above is:

float **m1 = malloc(R * sizeof(*m1));

which is far less error prone, and if you ever changed the type of m1,
you only need to do it in one place. (BTW, why aren't you using
doubles?)

Sinan
 
V

vittorio

A. Sinan Unur said:
<code snipped>

Please indent properly and consistently, and use some extra whitespace.

I see no error-checking for the fopen, fscanf, and malloc calls.

There are quite a few extra-ugly casts floating around.

I would first see what fscanf returns, and whether R and C contain what
you thought they should.

Sinan
Sinan,
as I said even shortening the program at the line
"fscanf(fp,"%d%d",&R,&C);" lcc-win32 compiles smoothly but don't exewcute
it giving the same lcc runtime exception. Therefore, No way to check what R
& C are like. While - I repeat under freebsd no problems!

By the way a lessical question: what do you exactly mean with "...There are
quite a few extra-ugly casts floating around...": what are extra-ugly
casts?

Ciao
Vittorio
 
O

Old Wolf

vittorio said:
for(i=0;i<R;i++)
free(m1);
free(m2);


You try to free m2[R]. But m2 only has valid indices 0 ... (R-1).
This might be what's crashing your program.
I think you meant to write:

for (i = 0; i < R; ++i)
{
free(m1);
free(m2);
}

Also, do not cast the value returned by malloc.
It gains you nothing, and can be a source of errors.
 
A

A. Sinan Unur

....
Here you are a working-under-nix extract of the same long code I sent
to this NG causing the same error under lcc-win32 XP pro:

I edited your code a little:

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

int main(void){
int i,j;
int R,C;

float **m1;

FILE *fp;
fp = fopen("matrice.txt","r");
if ( !fp ) {
fprintf(stderr, "Cannot open matrice.txt\n");
exit(EXIT_FAILURE);
}
if ( 2 != fscanf(fp, "%d%d", &R, &C) ) {
fprintf(stderr, "Cannot read dimensions\n");
exit(EXIT_FAILURE);
}

printf("Rows: %d\tColumns: %d\n", R, C);

m1 = malloc(R * sizeof(*m1));
if ( !m1 ) {
fprintf(stderr, "Cannot allocate memory: Line: %d\n", __LINE__);
exit(EXIT_FAILURE);
}

for ( i = 0; i < R; i++ ) {
m1 = malloc(C * sizeof(*m1));
if ( !m1 ) {
fprintf(stderr, "Cannot allocate memory: Line: %d\n",
__LINE__);
exit(EXIT_FAILURE);
}
}

for ( i = 0; i < R; i++ ) {
for ( j = 0; j < C; j++ ) {
fscanf(fp, "%f", &m1[j]);
}
}

for ( i = 0; i < R; i++ ) {
for ( j = 0; j < C; j++ ) {
printf("%6.1f", m1[j]);
printf("\n");
}
fclose(fp);
}

return 0;
}

and ran it with the file you supplied:
matrice.txt
2 3
98.5 07.1 -2.3
86.5 -9.6 -8.4

Running on Win XP SP2 after compiling with lcc:

Rows: 2 Columns: 3
98.5
7.1
-2.3
86.5
-9.6
-8.4

"d:\home\asu1\usenet\clc\lcc\m1.exe"
Return code 0
Execution time 0.032 seconds
Press any key to continue...

I'll repeat: Add some error checking to your code.
 
V

vittorio

A. Sinan Unur said:
Then please provide the shortest possible code that we can compile by
just copying and pasting, along with sample input.


The following is an ugly cast:

#include <stdlib.h>

...

float **m1;
m1=(float**)malloc(sizeof(float*)*R);

The cast (float**) is not needed. It clutters the code, and if you ever
did forget to include stdlib.h, you would not get a warning.

From what I can surmise, the recommended replacement for the above is:

float **m1 = malloc(R * sizeof(*m1));

which is far less error prone, and if you ever changed the type of m1,
you only need to do it in one place. (BTW, why aren't you using
doubles?)

Here you are a working-under-nix extract of the same long code I sent to
this NG causing the same error under lcc-win32 XP pro:

lcc runtime
Exception 0xc0000005
segment violation
address 0x73d115ce

At the end the 3 lines of the file matrice.txt

Many thanks for your help
Vittorio


===================================================0
#include <stdio.h>
#include <stdlib.h>


void main(void){
int i,j;
int R,C;

/*Leggo matrice.txt,trasferendo i valori in una matrice m1 di reali
allocata dinamicamente*/
FILE *fp;
fp=fopen("matrice.txt","r");
fscanf(fp,"%d%d",&R,&C);

float **m1;
m1=(float**)malloc(sizeof(float*)*R);
for(i=0;i<R;i++)
m1=(float*)malloc(sizeof(float)*C);

for(i=0;i<R;i++)
for(j=0;j<C;j++)
fscanf(fp,"%f",&m1[j]);


for(i=0;i<R;i++){
for(j=0;j<C;j++)
printf("%6.1f",m1[j]);
printf("\n");
}
fclose(fp);
}
====================================================
matrice.txt
2 3
98.5 07.1 -2.3
86.5 -9.6 -8.4
 
M

Mark McIntyre

Here you are a working-under-nix extract of the same long code I sent to
this NG causing the same error under lcc-win32 XP pro:

Please turn up warnings in your compiler.
#include <stdio.h>
#include <stdlib.h>


void main(void){

illegal declaration of main, which must return an int.
int i,j;
int R,C;

/*Leggo matrice.txt,trasferendo i valori in una matrice m1 di reali
allocata dinamicamente*/
FILE *fp;
fp=fopen("matrice.txt","r");

did this call succeed? You should check. This is a very possible
cause - I wonder where lcc-win32 creates its debug executables, in a
subdirectory maybe?
fscanf(fp,"%d%d",&R,&C);

float **m1;

Unless you have a very new compiler, you can't declare variables after
executable statements. I don't know if lcc-win32 suupports this/
m1=(float**)malloc(sizeof(float*)*R);

the cast is not required, and it is strongly recommended you do NOT
include it. Ben Pfaff has an excellent explanation of why on his
website. By the way, if your compiler complains about needing the
cast, its a C++ compiler.
for(i=0;i<R;i++)
m1=(float*)malloc(sizeof(float)*C);

for(i=0;i<R;i++)
for(j=0;j<C;j++)
fscanf(fp,"%f",&m1[j]);


missing indentation. Not critical, but confusing. I strongly recommend
braces, even for one-liners.
for(i=0;i<R;i++){
for(j=0;j<C;j++)
printf("%6.1f",m1[j]);
printf("\n");
}
fclose(fp);
}


This code works correctly, once the problems mentioned above are
fixed.
 
E

Emmanuel Delahaye

vittorio a écrit :
While I can compile the program below under freebsd via a simple:
gcc prog1.c -o prog1
and it runs smoothly, I'm experiencing annoying problems with lcc-win32
under windows xp pro. In fact, under wedit, I can smoothly compile the
program but when I try to execute it it ends with an "abnormal termination"
and a popup complains that:

lcc runtime
Exception 0xc0000005
segment violation
address 0x73d115ce

The weirdness is greater if you think that cutting many lines of the program
and stopping the execution imediatedly after the line
fscanf(fp,"%d%d",&R,&C);

lcc-win32 chokes on the same exception.

You don't test the return of fopen(). Anything can happen.

You code is full of useless cast but important things like error
checking is totally missing.

This works fine to me (I'm using Code::Blocks)

#include <stdio.h>
#include <stdlib.h>
#define FNAME "matrice.txt"

int main(void)
{
FILE *fp = fopen(FNAME, "r");

if (fp != NULL)
{
int R, C;

int err = fscanf(fp, "%d%d", &R, &C) != 2;

if (!err)
{
float **m1 = malloc (sizeof * m1 * R);

printf ("creating a %d x %d matrix\n", R, C);

if (m1 != NULL)
{
{
int i;
for (i = 0; i < R; i++)
{
m1 = malloc(sizeof * m1 * C);
err = m1 == NULL;
}
}

if (!err)
{
{
int i;
for (i = 0;i < R && !err;i++)
{
int j;
for (j = 0;j < C && !err;j++)
{
int n = fscanf(fp, "%f", &m1[j]);

err = n != 1;
}
}
}

if (!err)
{
printf ("%d x %d matrix created\n", R, C);
{
int i;
for (i = 0;i < R;i++)
{
int j;
for (j = 0;j < C;j++)
{
printf("%6.1f", m1[j]);
}
printf("\n");
}
}

{
float **m2 = malloc(sizeof * m2 * R);

if (m2 != NULL)
{
{
int i;
for (i = 0;i < R;i++)
{
m2 = malloc(sizeof * m2 * C);

err = m2 == NULL;
}
}

if (!err)
{
float *r = malloc(sizeof * r * R);

if (r != NULL)
{
float *c = malloc(sizeof * c * C);

if (c != NULL)
{
{
int i;
for (i = 0;i < R;i++)
{
int j;
r = 0;
for (j = 0;j < C;j++)
{
r += m1[j];
}
printf("r %8.1f \n", r);
}
}

{
int j;
for (j = 0;j < C;j++)
{
int i;
c[j] = 0;
for (i = 0;i < R;i++)
{
c[j] += m1[j];
}
printf("c %8.1f \n", c[j]);
}
}

{
int i;
for (i = 0;i < R;i++)
{
int j;
for (j = 0;j < C;j++)
{
m2[j] = r + c[j];
}
}
}

{
FILE *fo =
fopen("destinazione.txt", "w");

if (fo != NULL)
{
int i;
for (i = 0;i < R;i++)
{
int j;
for (j = 0;j < C;j++)
{
fprintf(fo, "%6.1f",
m2[j]);
}
fprintf(fo, "\n");
}

fclose(fo);
}
}
free(c), c = NULL;
}
free(r), r = NULL;
}

}

{
int i;
for (i = 0;i < R;i++)
{
free(m2);
}
}
free(m2);
printf ("matrix m2 freed\n");
}
}
}
else
{
printf ("input error (data)\n");
}

{
int i;
for (i = 0;i < R;i++)
{
free(m1);
}
}
}

free(m1), m1 = NULL;
printf ("matrix m1 freed\n");
}
}
else
{
printf ("input error (R,C)\n");
}
fclose(fp), fp = NULL;
}
else
{
perror(FNAME);
}

return 0;
}

The input file:

2 3
1 2 3
4 5 6

produces:

11.0 13.0 15.0
20.0 22.0 24.0

The standard output:

creating a 2 x 3 matrix
2 x 3 matrix created
1.0 2.0 3.0
4.0 5.0 6.0
r 6.0
r 15.0
c 5.0
c 7.0
c 9.0
matrix m2 freed
matrix m1 freed


Note : As you can see, due to an intense refactoring based on a dramatic
reducing of the variables scopes, the code has been prepared to be
modularized. You really should learn how to write functions, instead of
repeating the same things... It's boring...
 
J

jacob navia

Mark McIntyre a écrit :
Please turn up warnings in your compiler.




illegal declaration of main, which must return an int.




did this call succeed? You should check. This is a very possible
cause - I wonder where lcc-win32 creates its debug executables, in a
subdirectory maybe?




Unless you have a very new compiler, you can't declare variables after
executable statements. I don't know if lcc-win32 suupports this/

This is standard C. lcc-win32 supports it.
Declaring variables anywhere is supported since at least 2 years now.

jacob
 
K

Keith Thompson

jacob navia said:
Mark McIntyre a écrit : [...]
Unless you have a very new compiler, you can't declare variables
after
executable statements. I don't know if lcc-win32 suupports this/

This is standard C. lcc-win32 supports it.
Declaring variables anywhere is supported since at least 2 years now.

Yes, this is standard C. The current C standard is C99.
Unfortunately, the current standard is not (yet?) as widely supported
as the previous one, C90. Mixing declarations and statements can
still cause portability problems if you care about platforms that
don't have C99 compilers (or at least C90 compilers that support
mixing declarations and statements as an extension).
 
J

jacob navia

Keith Thompson a écrit :
jacob navia said:
Mark McIntyre a écrit :
[...]
Unless you have a very new compiler, you can't declare variables
after
executable statements. I don't know if lcc-win32 suupports this/

This is standard C. lcc-win32 supports it.
Declaring variables anywhere is supported since at least 2 years now.


Yes, this is standard C. The current C standard is C99.
Unfortunately, the current standard is not (yet?) as widely supported
as the previous one, C90. Mixing declarations and statements can
still cause portability problems if you care about platforms that
don't have C99 compilers (or at least C90 compilers that support
mixing declarations and statements as an extension).

I know Keith, but you will
NOT
have any of those problems using lcc-win32 !!! :)-)

I care about standards and implemented that quite a
while ago.

jacob
 
M

Mark McIntyre

Mark McIntyre a écrit :

This is standard C. lcc-win32 supports it.
Declaring variables anywhere is supported since at least 2 years now.

Fair enough. Still a risky habit to get into, if one ever uses a
different compiler.
 
K

Keith Thompson

jacob navia said:
Keith Thompson a écrit :
jacob navia said:
Mark McIntyre a écrit : [...]

Unless you have a very new compiler, you can't declare variables
after
executable statements. I don't know if lcc-win32 suupports this/

This is standard C. lcc-win32 supports it.
Declaring variables anywhere is supported since at least 2 years now.
Yes, this is standard C. The current C standard is C99.
Unfortunately, the current standard is not (yet?) as widely supported
as the previous one, C90. Mixing declarations and statements can
still cause portability problems if you care about platforms that
don't have C99 compilers (or at least C90 compilers that support
mixing declarations and statements as an extension).

I know Keith, but you will
NOT
have any of those problems using lcc-win32 !!! :)-)

Yes, jacob, we know that.

I do have one major problem with lcc-win32: it only works in a single
environment. Others may find it useful in spite of that. I don't.
I care about standards and implemented that quite a
while ago.

Great, but in the real world many of us still have to deal with
pre-C99 implementations, and it would be foolish to ignore that fact.

Fortunately that particular C99 feature, though it's nice to have, is
not essential. It's easy enough to restructure your code so that all
the declarations precede all the statements in each block. The
resulting code (assuming no other problems) is legal in both C90 and
C99.
 
V

Vittorio

Thanks for the complete re-editing of my original program.
You're right: I must learn to use more functions in programming and
master many other techniques. But you know, programming isn't only a
science is mainly an art to be learnt step by step from other artists!
Thank you indeed
Vittorio
 

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
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top