/* There seems to be a great deal of confusion regarding the mem_buffer and memory allocation in the C assignment. Let's set the record straight. All the memory your program is allowed to deal with is allocated in a single call to initAlloc in main. This function is provided for you. initAlloc sets up the mem_buffer which is a huge array referenced by a char *. Your myMalloc and myFree will be manipulating this buffer. There will never be a need to call the actual C functions MALLOC or FREE. DON'T CALL THOSE FUNCTIONS! So how can we use this buffer to store and access objects not of type char? The following example should be of help in understanding the processes of pointer aritmatic and type-casting that are essential for solving this problem. The example is built arround the storage of integers. ON REMUS and many other SUN machines, integers are stored as 4 bytes, with the most significan bits first (big endian). So the number 5 is represented as [0][0][0][5] (brackets around each byte) and the number 256 is represented by [0][0][1][0] and 258 is [0][0][1][2]. **********NOTE IF YOU DO THIS ON A DIFFERENT MACHINE********************** most modern (read x86) computer systems store integers with the least significant bits first (little endian). So the number 5 is represented as [5][0][0][0] (brackets around each byte) and the number 256 is represented as [0][1][0][0] and the number 258 is Represented as [2][1][0][0] The example will examine each byte by using a type cast to convert the integer pointer "in" to a character pointer. Here we go: */ #include int main(){ int x, in[3]; char * chp; in[0] = 5; // [0][0][0][5] on remus, backwards in x86 in[1] = 256; //[0][0][1][0] on remus in[2] = 258; //[0][0][1][2] on remus //the ubiquitous type cast chp = (char *) in; //point it at the first //byte of the //first integer //Now we access the 12 bytes 1 by 1. Notice I //use %d in the printf to print out the integer value //stored in THE SINGLE BYTE. I could use %c to print //out the character represented by each number, but most of //these are unreadable (for instance 5 is the character you get //by typing -a) for(x = 0; x < 12; x++){ printf("[%d]", *chp); //print the number in each BYTE chp += 1; //move pointer one byte up //the compiler reads this as //chp + 1 * sizeof(char) //= chp + 1 * 1 = chp + 1 if((x + 1) % 4 == 0) printf("\n"); //newlines for formatting } } /* A final caveat about typecasting. typecasting is a programmer's way of telling the machine "Look, I know what I'm doing here, and if I say treat what this pointer points at as a certain type, then just do it!" The machine won't argue with you, but you may hear a faint snicker if you shoot yourself in the foot as in this example: */ This example is built for remus. to do it on an x86 machine, put the 1 in c[1] int * ip; char c[3] ; c[0] = 0; c[1] = 0; c[2] = 1; //256 ip = (unsigned int *) c; //point ip at 2 bytes before c so it's looking at the //4 byte integer [0][0][1][?], if ?=0 then this = 256 //but that ? could be any data, and may not even be //in the programs memory segment (core dump ensues) printf ("%d\n", *ip); //something bad happens (bad data, seg fault, etc.) //snickering /* Try changing the declarations to char c[4] c[0] = 0; c[1] = 0; c[2] = 1; c[3] = 0; ip = (unsigned int *) c; and see the difference, it works now because there are no garbage values in the low order bits (on x86 machines the 1 goes in c[1] still). */ Feel free to e-mail me any questions you might have concerning this example -Tom Walsh thomaswa@cs.rutgers.edu