xj01+@andrew.cmu.edu (Xue Jue) (12/19/88)
I am try to allocate a list of integer pointers by the following short program.
But for some reason, after I compiled it and tried to run, it gave me a
Segmentation fault message. I couldn't see what's wrong there. Could anyone out
there give me some guide?
#include <stdio.h>
int *(*B);
main()
{
*B = (int *) calloc(18,sizeof(int));
}
By the way, this is on IBM RT work station. The same thing has been running on
IBM PC with microsoft C 5.0.
Thanks.
----jue xue
guy@auspex.UUCP (Guy Harris) (12/20/88)
>I am try to allocate a list of integer pointers by the following short >program. But for some reason, after I compiled it and tried to run, >it gave me a Segmentation fault message. I couldn't see what's wrong >there. Could anyone out there give me some guide? > >#include <stdio.h> >int *(*B); > >main() >{ > *B = (int *) calloc(18,sizeof(int)); >} The statement "*B = <expression>" means "assign the value of the <expression> to the object pointed to by 'B'". "B" is implicitly assigned a NULL pointer value by its declaration; therefore, it doesn't point to anything. As such, "assign the value of the <expression> to the object pointed to by 'B'" is a meaningless command, since there *is* no object pointed to by "B". The RT PC presumably catches attempts to dereference NULL pointers, as do several other C implementations. Why did you not just do ... int *B; main() { B = (int *) calloc(18, sizeof(int)); }
evil@arcturus.UUCP (Wade Guthrie) (12/21/88)
You found yourself a stray pointer! In article <8Xf3eSy00UkZ40cVE0@andrew.cmu.edu>, xj01+@andrew.cmu.edu (Xue Jue) writes: > #include <stdio.h> > int *(*B); what you're doing here, is setting B up to be a pointer to a pointer to an int so let's look at a <REALLY> simple model for what is going on in memory: variable type address contents B pointer to pointer good1 garbage1 (*B) pointer to int garbage1 garbage2 (**B) int garbage2 garbage3 > main() > { Just an aside, you might declare calloc to return a pointer rather than an int (default): char * calloc(); /* this'll help */ > *B = (int *) calloc(18,sizeof(int)); When you do this, calloc allocates space for 18 ints somewhere in memory, and passes this back to the thing to which B points. Let's look at this in two steps: 1) calloc allocates space for 18 ints variable type address contents B pointer to pointer good1 garbage1 (*B) pointer to int garbage1 garbage2 (**B) int garbage2 garbage3 (none) int (18 of them) good2 garbage4 And put that address (good2, in this case) into the thing to which B points: variable type address contents B pointer to pointer good1 garbage1 (*B) pointer to int garbage1 good2 (**B) int (18 of them) good2 garbage4 > } What you have succeeded in doing is putting an address at a garbage value in memory (the address garbage1). You need first to assign B to point to something for which space has been allocated. I find that memory maps like these help to sort out what is going on. The segmentation fault was when you put something (in this case, the address good2) into a location which was out of the legally addressable memory > By the way, this is on IBM RT work station. The same thing has been > running on IBM PC with microsoft C 5.0. Maybe the IBM RT initializes variables to zero, making garbage1 actually NULL, and doesn't allow dereferencing a NULL pointer (a very wise practice, since it is non portable). The IBM PC does not set variables to zero, so you were really corrupting the heap. If your program was small, chances are that you would not see the error. If this same program grew to the point where you were corrupting data and/or code, then the debugging job would be monsterous (because the bug would have been there since God invented dirt, but the places to look for bugs are the most recently written routines). Wade Guthrie Rockwell International Anaheim, CA (Rockwell doesn't necessarily believe / stand by what I'm saying; how could they when *I* don't even know what I'm talking about???)
hermit@shockeye.UUCP (Mark Buda) (12/21/88)
In article <8Xf3eSy00UkZ40cVE0@andrew.cmu.edu> xj01+@andrew.cmu.edu (Xue Jue) writes: >I am try to allocate a list of integer pointers by the following short program. >But for some reason, after I compiled it and tried to run, it gave me a >Segmentation fault message. I couldn't see what's wrong there. Could anyone out >there give me some guide? > > >#include <stdio.h> >int *(*B); > >main() >{ > *B = (int *) calloc(18,sizeof(int)); >} Wow, a question I can answer, if not clearly (or correctly) :-) Problem 1: You are allocating memory for 18 ints, not 18 pointers to ints. Try calloc(18,sizeof(int *)); Problem 2: If you were allocating memory for pointers to ints, you would want to cast the value returned by calloc to an (int **), not an (int *). Problem 3: You are storing the pointer returned by calloc() in *B. This is very very bad. What you want is to store it in B. Storing it in *B puts it in the memory location B points to, and since B is never given a value, it doesn't really point anywhere useful. In fact, it is probably NULL. And as we all know, dereferencing a NULL pointer can mess up your day. >By the way, this is on IBM RT work station. The same thing has been running on >IBM PC with microsoft C 5.0. Shows you something about the IBM PC... :-) -- Mark Buda / Smart UUCP: hermit@shockeye.uucp / Phone(work):(717)299-5189 Dumb UUCP: ...rutgers!bpa!vu-vlsi!devon!shockeye!hermit I hate this $%$@%!$@%!@$%@#$@!% machine. "A little suction does wonders." - Gary Collins