Back to Operating Systems Home Page
Next: Additional Instructions (Assig. 1)
Up: 1997 term messages
Previous: Assig 1. To ASCII
[ This is in reply to a fairly basic question about C. However, it seems
that several people are stumbling on this same error, or very similar ones,
so I thought it useful to forward my reply to the list.
Feel free to skip, you all veterans of C hack wars ;-)
]
> I am having a big problem with with my program, I am trying to store all
> the individual words of my file into an array, ( i.e. char **array)....
> I allocated memory for this array of strings as follows...
>
> array= (char**)malloc(word*sizeof(*str));
>
> word is the number of words to be stored, and *str is the pointer that
> contains each individual word
This call to malloc allocates an array composed of a number of cells equal to
"word", each large enough to contain one CHAR, not POINTER_TO_CHAR. This
because if str is declared as:
char *str;
then
a) str is a pointer variable: one large enough to contain the address
of a character.
b) *str is a character variable: the character whose address happens
to be contained in str.
hence sizeof(*str) is the size of one character. So the right way to
allocate the array is
array = (char**)malloc(word*sizeof(char*));
Remember that sizeof can take for argument both a variable name and a
type name (char*, in this case).
Note also that the above malloc call allocates the needed to store
the POINTERS to the strings of the array, not the storage needed to
store the strings themselves. In other words, after that malloc the
pointers point to nothing, and just contain garbage addresses.
> ( i assume that every word in the file is less than 25 characters long)
AreYouSureAnAssumptionLikeThisMakesSense?PerhapsYouShouldReadAbout->fgets(3);
(gee, am I giving out one hint too many?
...and two more: strdup(3), strtok(3) ;-)
> the problem arises when I try to copy *str into **array, I get a
> segmentation error... i.e. the following line seems to screw me up
>
> **array++ = *str;
Same error as before: an excess of * on both sides.
Given the declarations:
char **array, *str;
it follows that:
*array and str are both of char* type, i.e. something that can
point to a string like "this", i.e. contain the address of
the 't' in "this"
**array and *str are of type char, i.e. something like 't' (-his);
So the "effect" of your expression above is to increment a character
(e.g., 't' into 'u'), and then assign to it whatever str is pointing
to: probably garbage, in accordance to Murphy's Law.
\
Franco Callari