From: Spiro Trikaliotis (trik-news_at_gmx.de)
Date: 2003-01-23 10:42:06
Hallo Tim, Tim Schürmann schrieb: > Spiro Trikaliotis schrieb: > > > Groepaz: There is a difference. In your code, TestStruct contains > > a pointer to some area. This is not true with Christian's wanted > > solution. > > > > Look at this: > > > > TestStruct *a = malloc(sizeof(TestStruct)+sizeof(unsigned char)*100); > > > With this, you get a TestStruct which contains 100 elements (0..99) > > [in case the 0 does not work, and David's suggestion has to be applied, > > it is 101, ie., 0..100]. > > > Sorry, but i don't understand your argumentation. > What you got there is, that TestStruct points to a beginning of the > allocated memory of 1 TestStruct (why do you "malloc" the TestStruct? > TestStruct already exist) well, the type TestStruct exists, but there isn't memory for it. Look at my definition: > > TestStruct *a = malloc(sizeof(TestStruct)+sizeof(unsigned char)*100); I only define a pointer to a TestStruct (TestStruct *) named a. For this, I reserve the memory for the TestStruct plus 100 bytes at the end. This is not true for Groepaz solution: Here, you reserve memory for the TestStruct (which contains x Bytes for a pointer to a buffer of chars!) plus the 100 bytes at the end. This is x bytes more. > plus 100 Elements of unsigned char. So, does data > point automaticly to the right allocated "char-Memory"? If this is true, > the same line should work with Groepaz solution. No, there is no pointer to the right allocated "char-memory". In fact, you do not need anymore pointer. Look at this: With my solution, the TestStruct looks like +-----------------------+ | unsigned char width | +-----------------------+ | unsigned char height | +-----------------------+ | unsigned char data[0] | +-----------------------+ | unsigned char data[1] | +-----------------------+ | unsigned char data[2] | +-----------------------+ | ... ... ... | . . . . . . | ... ... ... | +-----------------------+ | unsigned char data[99]| +-----------------------+ } With groepaz' solution, you have +-----------------------+ | unsigned char width | +-----------------------+ | unsigned char height | +-----------------------+ | unsigned char *data | ----------------------------+ +-----------------------+ | | You have to reserve memory for data separately, so | you get some more memory: | | +-----------------------+ | | unsigned char _[0] | <----------------------------+ +-----------------------+ | unsigned char _[1] | +-----------------------+ | unsigned char _[2] | +-----------------------+ | ... ... ... | . . . . . . | ... ... ... | +-----------------------+ | unsigned char _[99] | +-----------------------+ > My C-Standard book (german version of Kernighan and Richie) says, that > > char a[]; > and > char *a; > > are the same. Arrays acts like pointers (btw: are arrays realised as > pointers?). That's why you could write a[i] or *(a+i) and if pa is a > pointer and a the array you can do > pa=a > and > pa++ > to get the next element. *sigh* The old array vs. pointer discussion... No, pointer and arrays are not (always) the same. In this case, the are not. They appear to be the same because C defines an implicit cast from an array to a pointer. 1. char a[]; and 2. char *a; seem to be the same, yes. Both defined something named "a" where I can put something into. Both don't reserve memory for the things to store - it seems, but this is not true! While 1. doesn't reserve any memory, with 2., there is memory reserved for one pointer. So, while the compiler just knows at compile time where the storage (none) for a is located , it doesn't for a in 2. With 2, whenever a is used, the compiled program has to dereference the pointer. It does not have to do so with a, since it does know where the storage for a is. One has to remark that with 1., the programme has to make sure that there is enough memory after a for something to be stored. You cannot be sure if you use automatic or global variables, but in the case of the structs, you can be (well, almost...) Another example which might help: Look at this: struct { char is_byte[0]; int is_int; }; Although this is *not* good programming practice, you can use it to get each byte of an int (I assume 32 bit ints here). Assume we have a low-endian machine, then is_byte[0] is the lowest byte of is_int is_byte[1] is the lower-middle byte of is_int is_byte[2] is the higher-middle byte of is_int is_byte[3] is the highest byte of is_int This assumes that the fields of the struct are not rearranged, and there is no padding involved, this is the reason I would call it bad programming practice. But it works (at least, on most machines/compilers)! I hope this clarifies a little bit, Spiro. ---------------------------------------------------------------------- To unsubscribe from the list send mail to majordomo_at_musoftware.de with the string "unsubscribe cc65" in the body(!) of the mail.
This archive was generated by hypermail 2.1.3 : 2003-01-23 10:42:12 CET