nol2321@dsacg2.dsac.dla.mil (Jim Dunn) (08/21/90)
Well, no one took me up on my offer of checking out the Curses Source I've been working on, so I'll ask a "more direct and specific" question... Why can't I do the following?!? (C'mon you gurus...) ---Cut Here--- #include <stdio.h> typedef struct _window { int x; int y; int **array; int beg_x; int beg_y; int max_x; int max_y; } WINDOW; main() { int x, xL = 10; WINDOW *w1; w1 = (WINDOW *) malloc(sizeof(WINDOW)); /* the problem is next */ w1->array = malloc( xL * sizeof(int) ); /* isn't the above line legal, or how can I allocate mem for the storage */ for(x=0;x < xL; x++) w1->array[x] = (int *) malloc( 10 * sizeof(int *) ); } This is setup for, let's say, a 10 x 10 matrix of ints, OK? It'll compile ok, but it'll lock up the machine... (at least on the PC). Jim jdunn@dsac.dla.mil
vu0310@bingvaxu.cc.binghamton.edu (R. Kym Horsell) (08/21/90)
In article <2409@dsacg2.dsac.dla.mil> nol2321@dsacg2.dsac.dla.mil (Jim Dunn) writes: \\\ >/* the problem is next */ > w1->array = malloc( xL * sizeof(int) ); >/* isn't the above line legal, or how can I allocate mem for the storage */ \\\ The first, minor, problem is that you haven't declared the prototype for malloc(). You'd better say extern char *malloc(); at the top or include the appropriate header (malloc.h is std but some PCs use alloc.h). This'll fix other problems when you try to change memory models. The main problem is that you didn't allocate the array, only the *rows* of the array. Better put w1->array = (int**)malloc(10 * sizeof(int*)); before the for-loop; otherwise there isn't anywhere for the ``row-of-rows'' to be stored! The final point: inside the for-loop you have said the array elements are int* -- i gather you really want to store ints in them so: w1->array[x] = (int*)malloc(10*sizeof(int)); Hope this helps, -Kym Horsell P.S. please don't edit the "Newsgroups" line.
ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (08/21/90)
In article <3871@bingvaxu.cc.binghamton.edu>, vu0310@bingvaxu.cc.binghamton.edu (R. Kym Horsell) writes: > extern char *malloc(); > at the top or include the appropriate header (malloc.h is std but ^^^^^^^^^^^^^^^ In ANSI-compliant compilers, the prototype for malloc() can be found in <stdlib.h>. The ANSI standard does not require any <malloc.h>, though there is nothing to stop an implementation providing such a thing. -- The taxonomy of Pleistocene equids is in a state of confusion.
rmj@tcom.stc.co.uk (Rhodri James) (08/21/90)
In article <2409@dsacg2.dsac.dla.mil> nol2321@dsacg2.dsac.dla.mil (Jim Dunn) writes: >Why can't I do the following?!? (C'mon you gurus...) > >typedef struct _window { > int x; > int y; > int **array; [etc] >} WINDOW; > >main() >{ > int x, xL = 10; > WINDOW *w1; > > w1 = (WINDOW *) malloc(sizeof(WINDOW)); > >/* the problem is next */ > w1->array = malloc( xL * sizeof(int) ); You want the whole list or just the short version? :-) 1) array is an int ** so the malloc should be cast to that 2) the "elements" are int *, so that should be what you take sizeof. Pointers haven't been equivalent to ints for some while. 3) this isn't vastly relevant to PC applications, but doing a multiplication as your argument to malloc is just asking for alignment trouble. Either calloc(xL, sizeof(int *)), or (more grungily) malloc(sizeof(int *[xL])) (will this work if xL is a variable?) 4) you really ought to consider #defining xL rather than making it a variable. Unless you have pressing reasons otherwise. >/* isn't the above line legal, or how can I allocate mem for the storage */ It's legal, but hardly sensible. Actually, it isn't all that legal. > for(x=0;x < xL; x++) > w1->array[x] = (int *) malloc( 10 * sizeof(int *) ); This time you should be taking the sizeof an int! Comments above about multiplicative mallocs apply, and this time malloc( sizeof(int[10])) does work (I think). >} > >Jim >jdunn@dsac.dla.mil Hope this helps. Rhodri -- * Windsinger * "Nothing is forgotten..." * rmj@islay.tcom.stc.co.uk * Mike Whitaker * or (occasionally) * "...except sometimes the words" * rmj10@phx.cam.ac.uk * Phil Allcock
volpe@underdog.crd.ge.com (Christopher R Volpe) (08/22/90)
In article <1884@jura.tcom.stc.co.uk>, rmj@tcom.stc.co.uk (Rhodri James) writes: |>You want the whole list or just the short version? :-) |> |>1) array is an int ** so the malloc should be cast to that |>2) the "elements" are int *, so that should be what you take sizeof. |>Pointers haven't been equivalent to ints for some while. |>3) this isn't vastly relevant to PC applications, but doing a |>multiplication as your argument to malloc is just asking for alignment |>trouble. Either calloc(xL, sizeof(int *)), or (more grungily) |>malloc(sizeof(int *[xL])) (will this work if xL is a variable?) First, malloc doesn't know or care (and couldn't find out if it wanted to) whether the argument being passed in is a constant expression (like sizeof(anything)) or an expression computed at runtime via a multiplication. My copy of K&R II says (section 7.8.5) that the pointer returned by malloc or calloc has proper alignment for the object in question. My manpage (SunOS 4.0.?) says that calloc USES malloc to allocate the storage, and then initializes it to zeros. Second, types must have a size determinable at compile time, since sizeof yields a constant expression. So, (int *[xL]) is not a legal type. AND EVEN IF IT WERE LEGAL, the value produced would be the same as (xL * sizeof(int *)), so malloc wouldn't know the difference. |>Rhodri |>-- |>* Windsinger * "Nothing is forgotten..." |>* rmj@islay.tcom.stc.co.uk * Mike Whitaker |>* or (occasionally) * "...except sometimes the words" |>* rmj10@phx.cam.ac.uk * Phil Allcock ================== Chris Volpe G.E. Corporate R&D volpecr@crd.ge.com
nol2321@dsacg4.dsac.dla.mil (Jim Dunn) (08/22/90)
Well, I appreciate ALL the suggestions that everyone has made. You've truly opened my eyes to my own ignorance, actually you've opened my eyes to my typos... You see, I was typing the program in from reading a bad program listing. Most of the (int *)'s WERE (int)... So, now I've written a small sample demo program, using all the suggestions, and will explain my use... This **int matrix is for use with a direct screen write project. Instead of declaring a **char, I want to use a **int since the PC SCREEN is set up with an attribute byte and then an actual character byte. Such that: int **junk; junk[1][3] = (attr<<8) | chr; OK? I won't bother you with a net posting of the source samples, but if anyone would be interested in giving it a look see, please e-mail me and I'll ship you the source. It's a new implementation of Curses using direct screen write... Jim jdunn@dsac.dla.mil
rmj@tcom.stc.co.uk (Rhodri James) (08/30/90)
In article <11245@crdgw1.crd.ge.com> volpe@underdog.crd.ge.com (Christopher R Volpe) writes: >In article <1884@jura.tcom.stc.co.uk>, rmj@tcom.stc.co.uk (Rhodri James) >writes: >|>3) this isn't vastly relevant to PC applications, but doing a >|>multiplication as your argument to malloc is just asking for alignment >|>trouble. Either calloc(xL, sizeof(int *)), or (more grungily) >|>malloc(sizeof(int *[xL])) (will this work if xL is a variable?) Several people have pointed out to me that it won't work if xL is a variable. I wasn't sure, but I really should have known. Thankyou, one and all. And now to business. >First, malloc doesn't know or care (and couldn't find out if it wanted >to) whether the argument being passed in is a constant expression >(like sizeof(anything)) or an expression computed at runtime via >a multiplication. My copy of K&R II says (section 7.8.5) that the >pointer returned by malloc or calloc has proper alignment for the >object in question. My manpage (SunOS 4.0.?) says that calloc USES >malloc to allocate the storage, and then initializes it to zeros. Yes, K&R 2 says the *pointer* has proper alignment for the object in question, by taking the most restrictive possibility, and I wouldn't be surprised if calloc were implemented by using malloc. However, note the emphasis and read on... >[...] the value produced [by sizeof(int *[xL]) if it were legal] would be the >same as (xL * sizeof(int *)), so malloc wouldn't know the difference. This is not guarenteed true for all types by anything I can find in K&R 2. The crux of the potential health hazard comes with the definition of sizeof, which K&R2 says (section 6.3) gives a size_t result equal to the size of the specified object or type in bytes. Nothing here guarentees that the *end* of the object will be such that another object straight after it in memory (which is what the multiplication implies) will be correctly aligned. Many structs would give appropriately odd lengths; I'm sure you don't need examples. I admit I jumped too fast on int *, which is OK (probably, on most modern machines), and I don't have a copy of the standard. Can anyone quote chapter and verse invalidating this argument (please)? -- * Windsinger * "Nothing is forgotten..." * rmj@islay.tcom.stc.co.uk * Mike Whitaker * or (occasionally) * "...except sometimes the words" * rmj10@phx.cam.ac.uk * Phil Allcock
volpe@underdog.crd.ge.com (Christopher R Volpe) (08/30/90)
In article <1912@islay.tcom.stc.co.uk>, rmj@tcom.stc.co.uk (Rhodri James) writes: |>In article <11245@crdgw1.crd.ge.com> volpe@underdog.crd.ge.com (Christopher R Volpe) writes: |>>First, malloc doesn't know or care (and couldn't find out if it wanted |>>to) whether the argument being passed in is a constant expression |>>(like sizeof(anything)) or an expression computed at runtime via |>>a multiplication. My copy of K&R II says (section 7.8.5) that the |>>pointer returned by malloc or calloc has proper alignment for the |>>object in question. My manpage (SunOS 4.0.?) says that calloc USES |>>malloc to allocate the storage, and then initializes it to zeros. |> |>Yes, K&R 2 says the *pointer* has proper alignment for the object in |>question, by taking the most restrictive possibility, and I wouldn't be |>surprised if calloc were implemented by using malloc. However, note the |>emphasis and read on... |> |>>[...] the value produced [by sizeof(int *[xL]) if it were legal] would be the |>>same as (xL * sizeof(int *)), so malloc wouldn't know the difference. |> |>This is not guarenteed true for all types by anything I can find in K&R 2. You can find it in K&R2 in sec. 6.3 (page 135 in my copy). It says, "The size of the array is the size of one entry times the number of entries, so the number of entries is just sizeof(keytab)/sizeof(struct key) ... Another way to write this is to divide the array size by the size of a specific element... sizeof(keytab)/sizeof(keytab[0]) " |>The crux of the potential health hazard comes with the definition of |>sizeof, which K&R2 says (section 6.3) gives a size_t result equal to the |>size of the specified object or type in bytes. Nothing here guarentees |>that the *end* of the object will be such that another object straight |>after it in memory (which is what the multiplication implies) will be |>correctly aligned. Many structs would give appropriately odd lengths; |>I'm sure you don't need examples. They would have to be padded by the compiler to make the above statement (Sec 6.3) work out correctly. ================== Chris Volpe G.E. Corporate R&D volpecr@crd.ge.com
bruce@seismo.gps.caltech.edu (Bruce Worden) (08/31/90)
In article <1912@islay.tcom.stc.co.uk> rmj@htc1.UUCP (Rhodri James) writes: [material deleted] >The crux of the potential health hazard comes with the definition of >sizeof, which K&R2 says (section 6.3) gives a size_t result equal to the >size of the specified object or type in bytes. Nothing here guarentees >that the *end* of the object will be such that another object straight >after it in memory (which is what the multiplication implies) will be >correctly aligned. Many structs would give appropriately odd lengths; >I'm sure you don't need examples. Actually, examples would be nice, since I don't see what you mean. On a machine requiring alignment: struct thingy { char a; } sizeof(struct thingy) is 1. struct thingy { int i; /* four byte ints */ } sizeof(struct thingy) is 4. struct thingy { int i; char a; } sizeof(struct thingy) is 8. The structure is padded to insure that alignment is maintained. > ... Can anyone >quote chapter and verse invalidating this argument (please)? I don't know what the standard says about the issue (if anything), but it is difficult to imagine a serious vendor shipping a system that required more than single byte alignment and in which the structure in the last example was size 5. It is not so much a question of the standard, but, rather, one of functionality. -------------------------------------------------------------------------- C. Bruce Worden bruce@seismo.gps.caltech.edu 252-21 Seismological Laboratory, Caltech, Pasadena, CA 91125
henry@zoo.toronto.edu (Henry Spencer) (08/31/90)
In article <1912@islay.tcom.stc.co.uk> rmj@htc1.UUCP (Rhodri James) writes: >The crux of the potential health hazard comes with the definition of >sizeof, which K&R2 says (section 6.3) gives a size_t result equal to the >size of the specified object or type in bytes. Nothing here guarentees >that the *end* of the object will be such that another object straight >after it in memory (which is what the multiplication implies) will be >correctly aligned... Please take a long hard look at section A7.4.8 of K&R2. The numbered chapters, useful though they are, are *not* meant as a precise definition of the language; they are a tutorial. Appendix A is the reference manual. Actually, if you want a definitive reference you have to look at the ANSI C standard itself, but in fact K&R2 A7.4.8 clears this issue up quite satisfactorily. -- TCP/IP: handling tomorrow's loads today| Henry Spencer at U of Toronto Zoology OSI: handling yesterday's loads someday| henry@zoo.toronto.edu utzoo!henry
gordon@sneaky.UUCP (Gordon Burditt) (09/02/90)
>>[...] the value produced [by sizeof(int *[xL]) if it were legal] would be the >>same as (xL * sizeof(int *)), so malloc wouldn't know the difference. > >This is not guarenteed true for all types by anything I can find in K&R 2. >The crux of the potential health hazard comes with the definition of >sizeof, which K&R2 says (section 6.3) gives a size_t result equal to the >size of the specified object or type in bytes. Nothing here guarentees >that the *end* of the object will be such that another object straight >after it in memory (which is what the multiplication implies) will be >correctly aligned. Many structs would give appropriately odd lengths; >I'm sure you don't need examples. ANSI C standard 3.3.3.4 "The sizeof operator": ... Another use of the sizeof operator is to compute the number of members in an array: sizeof array / sizeof array[0] end quote Set '=' to mean mathematical equation, not C assignment. Set '/' to mean C integer division. If you have an array of structs, then: number_elements = sizeof array / sizeof array[0] If the array is some structs plus external padding (the total padding in the whole array), sizeof array = number_elements * sizeof struct foo + external_padding_bytes Substituting, number_elements = ((number_elements * sizeof struct foo) + external padding bytes) / sizeof struct foo number_elements = number_elements + external_padding_bytes / sizeof struct foo 0 = external_padding_bytes / sizeof struct foo If you make the dimension of the array much larger than sizeof struct foo, then the total number of external padding bytes in the array must be much less than one per array element. This pretty much kills the alignment argument. Sizeof must include trailing padding and internal padding in a structure. And there cannot be any *LEADING* padding for other reasons. Gordon L. Burditt sneaky.lonestar.org!gordon