Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > strange behavior

Reply
Thread Tools

strange behavior

 
 
Marlene Stebbins
Guest
Posts: n/a
 
      04-23-2004
Something very strange is going on here. I don't know if it's a C
problem or an implementation problem. The program reads data from
a file and loads it into two arrays. When xy, x, y, *xlist and
*ylist are ints or floats there is no apparent problem. If these
variables are doubles, the program crashes. Furthermore, the
crashes occur only when xlist and ylist are free()ed. When the
above variables are doubles and the calls to free() are
eliminated, the program doesn't crash, but the output is weird.

If there is anyone out there with enough time on his hands to
compile this code and play with it, I would appreciate getting
your opinion. Don't forget to change the format specifiers in the
calls to fscanf() when changing types. Here are data for the
input file:

0 12 5 12 8 9 11 3 10 -2 5 -8 0 -10 -7 -1 -7 12

/* Read xy data from a file.
Load x&y values into respective arrays.
Works with ints, floats, but not doubles???
*/
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
double xy, x, y;
double *xlist, *ylist;
int xct, yct, xycount, idx;
FILE *data;

if((data = fopen("vertices.txt", "r")) == NULL)
{
fprintf(stderr, "can't open data file\n");
exit(EXIT_FAILURE);
}
xycount = 0;
while(fscanf(data, "%lf") == 1)
xycount++;
if(xycount%2 != 0)
{
fprintf(stderr, "unequal number of x,y values\n");
exit(EXIT_FAILURE);
}
xlist = calloc(xycount/2, sizeof(xlist));
ylist = calloc(xycount/2, sizeof(ylist));
rewind(data);
xct = 0;
yct = 0;
while(fscanf(data, "%lf %lf", &x, &y) == 2)
{
xlist[xct++] = x;
ylist[yct++] = y;
}
fclose(data);

for(idx = 0; idx < xycount/2; ++idx)
printf("%4.f", xlist[idx]);
putchar('\n');
for(idx = 0; idx < xycount/2; ++idx)
printf("%4.f", ylist[idx]);
putchar('\n');

free(xlist);
free(ylist);

return 0;
}



 
Reply With Quote
 
 
 
 
Christopher Benson-Manica
Guest
Posts: n/a
 
      04-23-2004
Marlene Stebbins <(E-Mail Removed)> spoke thus:

> while(fscanf(data, "%lf") == 1)

^
Where is the float you're reading going? If this is your actual code,
no wonder it crashes. If you want to ignore some input, use

fscanf( data, "%*lf" ); /* legal */

I have no idea whether that's the root of the behavior you describe,
but it's definitely a problem.

--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
 
Reply With Quote
 
 
 
 
Neil Cerutti
Guest
Posts: n/a
 
      04-23-2004
In article <(E-Mail Removed)>, Marlene Stebbins wrote:
> Something very strange is going on here.>
>
> xlist = calloc(xycount/2, sizeof(xlist));
> ylist = calloc(xycount/2, sizeof(ylist));


You want

xlist = calloc(xycount/2, sizeof *xlist);
ylist = calloc(xycount/2, sizeof *ylist);

The reason that other types of lists work is a coincedence of,
e.g., sizeof xlist and sizeof *xlist.

--
Neil Cerutti
"Do you wanna see 'em?"
"See what?"
"The corpses. They're in the basement." --_Return of the Living Dead_.
 
Reply With Quote
 
Marlene Stebbins
Guest
Posts: n/a
 
      04-23-2004
Christopher Benson-Manica wrote:
> Marlene Stebbins <(E-Mail Removed)> spoke thus:
>
>
>> while(fscanf(data, "%lf") == 1)

>
> ^
> Where is the float you're reading going? If this is your actual code,
> no wonder it crashes. If you want to ignore some input, use
>
> fscanf( data, "%*lf" ); /* legal */
>
> I have no idea whether that's the root of the behavior you describe,
> but it's definitely a problem.
>


OK, thanks. Doesn't affect the strange behavior though.

Marlene



 
Reply With Quote
 
Kevin Bagust
Guest
Posts: n/a
 
      04-23-2004
In article <(E-Mail Removed)>,
Marlene Stebbins <(E-Mail Removed)> wrote:
> xlist = calloc(xycount/2, sizeof(xlist));
> ylist = calloc(xycount/2, sizeof(ylist));


These two lines should be:
xlist = calloc( xycount/2, sizeof( *xlist ));
ylist = calloc( xycount/2, sizeof( *ylist ));

Because without dereferencing xlist or ylist you are getting enough
memory for pointers to the type, rather that for the type it self.

From your description I would guess that the size of a pointer is larger
or equal to the size of an int or a float. Where as the size of a pointer
is smaller than the size of a double, so with double you were over
writing other memory and so getting strange results and crashes.

Kevin.

 
Reply With Quote
 
Ralf Damaschke
Guest
Posts: n/a
 
      04-23-2004
Christopher Benson-Manica <(E-Mail Removed)> wrote in
news:c6bicu$r9k$(E-Mail Removed):

> Marlene Stebbins <(E-Mail Removed)> spoke thus:
>
>> while(fscanf(data, "%lf") == 1)

> ^
> Where is the float you're reading going? If this is your
> actual code, no wonder it crashes. If you want to ignore some
> input, use
>
> fscanf( data, "%*lf" ); /* legal */


But useless when trying to test the number of input items
assigned as in the OP's program.

Better:
while (fscanf(data, "%lf", &xy) == 1)

> I have no idea whether that's the root of the behavior you
> describe, but it's definitely a problem.


Later on in program there is another problem:

>> xlist = calloc(xycount/2, sizeof(xlist));
>> ylist = calloc(xycount/2, sizeof(ylist));


We do not need space for some pointers but for doubles, i.e.
sizeof(*xlist).

Ralf
 
Reply With Quote
 
Marlene Stebbins
Guest
Posts: n/a
 
      04-23-2004
Neil Cerutti wrote:
> In article <(E-Mail Removed)>, Marlene Stebbins wrote:
>
>>Something very strange is going on here.>
>>
>> xlist = calloc(xycount/2, sizeof(xlist));
>> ylist = calloc(xycount/2, sizeof(ylist));

>
>
> You want
>
> xlist = calloc(xycount/2, sizeof *xlist);
> ylist = calloc(xycount/2, sizeof *ylist);
>
> The reason that other types of lists work is a coincedence of,
> e.g., sizeof xlist and sizeof *xlist.
>


Nice try. Still crashing after this change.

 
Reply With Quote
 
Marlene Stebbins
Guest
Posts: n/a
 
      04-23-2004
Ralf Damaschke wrote:
>>If you want to ignore some
>>input, use
>>
>>fscanf( data, "%*lf" ); /* legal */

>
>
> But useless when trying to test the number of input items
> assigned as in the OP's program.
>
> Better:
> while (fscanf(data, "%lf", &xy) == 1)
>
> Later on in program there is another problem:
>
>
>>> xlist = calloc(xycount/2, sizeof(xlist));
>>> ylist = calloc(xycount/2, sizeof(ylist));

>>

>
> We do not need space for some pointers but for doubles, i.e.
> sizeof(*xlist).


Thank you Ralf. These two changes fix the problem. Actually, I had

while (fscanf(data, "%lf", &xy) == 1)

originally, and changed it, thinking it inefficient. Live and learn.

Marlene








 
Reply With Quote
 
Darrell Grainger
Guest
Posts: n/a
 
      04-23-2004
On Fri, 23 Apr 2004, Marlene Stebbins wrote:

> Something very strange is going on here. I don't know if it's a C
> problem or an implementation problem. The program reads data from
> a file and loads it into two arrays. When xy, x, y, *xlist and
> *ylist are ints or floats there is no apparent problem. If these
> variables are doubles, the program crashes. Furthermore, the
> crashes occur only when xlist and ylist are free()ed. When the
> above variables are doubles and the calls to free() are
> eliminated, the program doesn't crash, but the output is weird.
>
> If there is anyone out there with enough time on his hands to
> compile this code and play with it, I would appreciate getting
> your opinion. Don't forget to change the format specifiers in the
> calls to fscanf() when changing types. Here are data for the
> input file:
>
> 0 12 5 12 8 9 11 3 10 -2 5 -8 0 -10 -7 -1 -7 12
>
> /* Read xy data from a file.
> Load x&y values into respective arrays.
> Works with ints, floats, but not doubles???
> */
> #include <stdio.h>
> #include <stdlib.h>
>
> int main(void)
> {
> double xy, x, y;
> double *xlist, *ylist;
> int xct, yct, xycount, idx;
> FILE *data;
>
> if((data = fopen("vertices.txt", "r")) == NULL)
> {
> fprintf(stderr, "can't open data file\n");
> exit(EXIT_FAILURE);
> }
> xycount = 0;
> while(fscanf(data, "%lf") == 1)
> xycount++;


Where are you storing the data that fscanf is reading it? This could cause
a program to crash. I'd use:

while(fscanf(data, "%lf", &xy) == 1)
xycount++;

> if(xycount%2 != 0)
> {
> fprintf(stderr, "unequal number of x,y values\n");
> exit(EXIT_FAILURE);
> }
> xlist = calloc(xycount/2, sizeof(xlist));
> ylist = calloc(xycount/2, sizeof(ylist));


Obviously the /2 is okay. You want to store half the list in xlist and the
other half in ylist. The problem here is that sizeof(xlist) is the size of
a pointer to double. You want the size of a double or sizeof(*xlist). Same
thing for ylist.

> rewind(data);
> xct = 0;
> yct = 0;
> while(fscanf(data, "%lf %lf", &x, &y) == 2)
> {
> xlist[xct++] = x;
> ylist[yct++] = y;
> }
> fclose(data);
>
> for(idx = 0; idx < xycount/2; ++idx)
> printf("%4.f", xlist[idx]);
> putchar('\n');
> for(idx = 0; idx < xycount/2; ++idx)
> printf("%4.f", ylist[idx]);
> putchar('\n');


Just as a side note, a good compiler will do this for you but I'm in the
habit of taking things like xycount/2 and replacing them with another
variable. In a for loop, like above, this is a chance division will occur
on each iteration of the loop. That could have a notble impact.

> free(xlist);
> free(ylist);
>
> return 0;
> }
>
>
>
>


--
Send e-mail to: darrell at cs dot toronto dot edu
Don't send e-mail to http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
Martin Ambuhl
Guest
Posts: n/a
 
      04-23-2004
Marlene Stebbins wrote:

> Something very strange is going on here. I don't know if it's a C
> problem or an implementation problem. The program reads data from a file
> and loads it into two arrays. When xy, x, y, *xlist and *ylist are ints
> or floats there is no apparent problem.


The problem is obvious, but may not be apparent to you. Your program
relies on sizeof(pointer-to-T) being equal to sizeof(T). You were
unlucky to have not seen this before because, it seems, your
implementation does have
sizeof(*int) == sizeof(int)
and
sizeof(*float) == sizeof(float)
but
sizeof(*double) != sizeof(double)
I'll bet
sizeof(*char) != sizeof(char)
and probably that
!(sizeof(*short) == sizeof(short) && sizeof(*long) == sizeof(long))


> If these variables are doubles,
> the program crashes.

[...]
> double *xlist, *ylist;

[...]
> while(fscanf(data, "%lf") == 1)


Could it be because the above has insufficient arguments for the format?

> xlist = calloc(xycount/2, sizeof(xlist));
> ylist = calloc(xycount/2, sizeof(ylist));


Or because the above makes no sense?

With these three lines corrected, the program below at least seems to
work properly:


/* Read xy data from a file.
Load x&y values into respective arrays.
Works with ints, floats, but not doubles???
*/
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
double xy, x, y;
double *xlist, *ylist;
int xct, yct, xycount, idx;
FILE *data;

if ((data = fopen("vertices.txt", "r")) == NULL) {
fprintf(stderr, "can't open data file\n");
exit(EXIT_FAILURE);
}
xycount = 0;
while (fscanf(data, "%lf", &xy) == 1)
xycount++;
if (xycount % 2 != 0) {
fprintf(stderr, "unequal number of x,y values\n");
exit(EXIT_FAILURE);
}
if (!(xlist = malloc(xycount / 2 * sizeof *xlist))) {
fprintf(stderr, "allocation failed for xlist, giving up\n");
exit(EXIT_FAILURE);
}
if (!(ylist = malloc(xycount / 2 * sizeof *ylist))) {
fprintf(stderr, "allocation failed for ylist, giving up\n");
free(xlist);
exit(EXIT_FAILURE);
}
rewind(data);
xct = 0;
yct = 0;
while (fscanf(data, "%lf %lf", &x, &y) == 2) {
xlist[xct++] = x;
ylist[yct++] = y;
}
fclose(data);

for (idx = 0; idx < xycount / 2; ++idx)
printf("%4.f", xlist[idx]);
putchar('\n');
for (idx = 0; idx < xycount / 2; ++idx)
printf("%4.f", ylist[idx]);
putchar('\n');

free(xlist);
free(ylist);

return 0;
}



 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Thunderbird strange behavior... Jim Firefox 5 11-17-2005 03:09 PM
Firefox 1.04 and Strange Find Behavior Thomas Firefox 5 06-28-2005 08:40 PM
utf8 pragma - strange behavior ryang Perl 1 04-11-2005 05:38 AM
strange behavior when using 'read' sstark Perl 0 03-06-2005 02:27 AM
undefined behavior or not undefined behavior? That is the question Mantorok Redgormor C Programming 70 02-17-2004 02:46 PM



Advertisments