pjh@mccc.edu (Peter J. Holsberg) (05/08/91)
Here is an extract from a program a student wrote. Note that he has declared "input" incorrectly. The strange behavior is that, when choice "1" is made, the print function outputs all but the first line that was entered. Can anyone explain that in terms of what scanf() is doing to memory near "input"? (This is on a 386, if endianism matters.) Thanks. ============================================================== #include <stdio.h> #include <string.h> void print(char *point[], int num); #define MAX 9 #define SIZE 80 #define RETURN "" main() { int i; int num = 0, return_value = 1; char sentence [MAX][SIZE]; /* an array of strings */ char *point[MAX]; /* an array of pointers to char */ char *orginal[MAX]; /* an array holding the orginal sequence */ char input; /* SHOULD HAVE BEEN int input!!! */ printf("Input up to ten sentences \n"); while(gets(sentence[num]) != NULL && num < MAX && strcmp(sentence[num], RETURN) != 0) { point[num] = orginal[num] = sentence[num]; num++; } printf("Make a choice: "); scanf ("%d" , &input); /* value converted to decimal integer but stored "in" a char ??? */ switch(input) { case 1: print(orginal,num); break; case 5: return; default: printf("Unknown response \n"); } } void print(char *pointer[], int num) { int count; for (count = 0 ; count < num ; count++) puts(pointer[count]); } ====================================== Pete -- Prof. Peter J. Holsberg Mercer County Community College Voice: 609-586-4800 Engineering Technology, Computers and Math UUCP:...!princeton!mccc!pjh 1200 Old Trenton Road, Trenton, NJ 08690 Internet: pjh@mccc.edu Trenton Computer Festival -- 4/20-21/91
ping@cubmol.bio.columbia.edu (Shiping Zhang) (05/09/91)
In article <1991May8.020720.20170@mccc.edu> pjh@mccc.edu (Peter J. Holsberg) writes: >Here is an extract from a program a student wrote. Note that he has >declared "input" incorrectly. The strange behavior is that, when choice >"1" is made, the print function outputs all but the first line that was >entered. Can anyone explain that in terms of what scanf() is doing to >memory near "input"? (This is on a 386, if endianism matters.) [...] > char sentence [MAX][SIZE]; /* an array of strings */ > char *point[MAX]; /* an array of pointers to char */ > char *orginal[MAX]; /* an array holding the orginal sequence */ > char input; /* SHOULD HAVE BEEN int input!!! */ [...] > printf("Make a choice: "); > scanf ("%d" , &input); /* value converted to decimal integer I think it results from declaring input as char and using it as int in scanf(). When scanf() writes 1 into the location of input, it puts into 0's those bits that belong to the first byte(s) of sentence[0], terminating sentence[0] at its first byte. I could be wrong, though. -ping
ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (05/09/91)
In article <1991May8.020720.20170@mccc.edu>, pjh@mccc.edu (Peter J. Holsberg) writes: > Here is an extract from a program a student wrote. Holsberg pointed out that a variable was declared char rather than int. In that program, on a little-endian machine, it will work; making the behaviour of longer and shorter integers consistent is what little-endian is _for_, after all. > #define MAX 9 > char sentence [MAX][SIZE]; /* an array of strings */ > printf("Input up to ten sentences \n"); There is a contradiction here. If sentence[] is to hold up to 10 sentences, MAX had better be 10, not 9! The input loop would be better as #define MAX 10 for (num = 0; num < 10 && gets(sentence[num]) != NULL && strcmp(sentence[num], "") != 0; num++) point[num] = original[num] = sentence[num]; Note: gets() has problems. Best to avoid it. See the FAQ. -- Bad things happen periodically, and they're going to happen to somebody. Why not you? -- John Allen Paulos.
pjh@mccc.edu (Pete Holsberg) (05/09/91)
In article <1991May8.204009.1694@cubmol.bio.columbia.edu> ping@cubmol.bio.columbia.edu (Shiping Zhang) writes: =In article <1991May8.020720.20170@mccc.edu> pjh@mccc.edu (Peter J. Holsberg) writes: =>Here is an extract from a program a student wrote. Note that he has =>declared "input" incorrectly. The strange behavior is that, when choice =>"1" is made, the print function outputs all but the first line that was =>entered. Can anyone explain that in terms of what scanf() is doing to =>memory near "input"? (This is on a 386, if endianism matters.) = =[...] = => char sentence [MAX][SIZE]; /* an array of strings */ => char *point[MAX]; /* an array of pointers to char */ => char *orginal[MAX]; /* an array holding the orginal sequence */ => char input; /* SHOULD HAVE BEEN int input!!! */ = =[...] = => printf("Make a choice: "); => scanf ("%d" , &input); /* value converted to decimal integer = =I think it results from declaring input as char and using it as int =in scanf(). When scanf() writes 1 into the location of input, it puts =into 0's those bits that belong to the first byte(s) of sentence[0], =terminating sentence[0] at its first byte. I could be wrong, though. I'm sure you're right. But what I really want to know is why the compiler assigns memory that way. It would seem to me that it would assign memory "downward," so that the attempt to write a 4 byte value into a 1 byte location would result in the "corruption" of the 3 cells *following* the one allocated to "input." Pete -- Prof. Peter J. Holsberg Mercer County Community College Voice: 609-586-4800 Engineering Technology, Computers and Math UUCP:...!princeton!mccc!pjh 1200 Old Trenton Road, Trenton, NJ 08690 Internet: pjh@mccc.edu Trenton Computer Festival -- 4/20-21/91
ping@cubmol.bio.columbia.edu (Shiping Zhang) (05/10/91)
In article <1991May9.161425.17079@mccc.edu> pjh@mccc.edu (Pete Holsberg) writes: <In article <1991May8.204009.1694@cubmol.bio.columbia.edu> ping@cubmol.bio.columbia.edu (Shiping Zhang) writes: <=In article <1991May8.020720.20170@mccc.edu> pjh@mccc.edu (Peter J. Holsberg) writes: <=>Here is an extract from a program a student wrote. Note that he has <=>declared "input" incorrectly. The strange behavior is that, when choice <=>"1" is made, the print function outputs all but the first line that was <=>entered. Can anyone explain that in terms of what scanf() is doing to <=>memory near "input"? (This is on a 386, if endianism matters.) <=[...] <=> char sentence [MAX][SIZE]; /* an array of strings */ <=> char *point[MAX]; /* an array of pointers to char */ <=> char *orginal[MAX]; /* an array holding the orginal sequence */ <=> char input; /* SHOULD HAVE BEEN int input!!! */ <= <=[...] <= <=> printf("Make a choice: "); <=> scanf ("%d" , &input); /* value converted to decimal integer <=I think it results from declaring input as char and using it as int <=in scanf(). When scanf() writes 1 into the location of input, it puts <=into 0's those bits that belong to the first byte(s) of sentence[0], <=terminating sentence[0] at its first byte. I could be wrong, though. <I'm sure you're right. But what I really want to know is why the <compiler assigns memory that way. It would seem to me that it would <assign memory "downward," so that the attempt to write a 4 byte value <into a 1 byte location would result in the "corruption" of the 3 cells <*following* the one allocated to "input." The memory space is allocated for those variables as a stack. The space for a later declared varible is put on the top of the stack with a smaller address. According to the order in which the variables are declared in this case, the space for input is on the top. After all I might be wrong in my previous post. In this case, it should be the pointer original[0] that is corrupted, making it point to an invalid location. You can actually check the location of those variables by printing out their addresses as in the following code: printf("sentence[0] %d, original[0] %d, input %d\n", (int) sentence, (int) original, (int) &input); -ping