addfive
. Change the function addfive()
and parts of main()
to use call-by-value instead.
#include<stdio.h> #include<stdlib.h> void addfive(int *value) { *value=(*value)+5; } int main(int argc, char **argv) { if(argc!=2) { printf("Usage: hw2i1a <integer>\n"); exit(1); } int times = atoi(argv[1]); int accumulator=0; while(times--) { printf("Accumulator = %d\n",accumulator); addfive(&accumulator); } }Turn-in requirement: submit your program as a file called
hw2i1a.c
in your hw2 directory, and add hw2i1a
as a target to the Makefile.
incrementCharAtOffset()
(and part of main()
) to use call-by-reference for this call instead.
#include<stdio.h> #include<stdlib.h> #include<string.h> struct LargeStruct { char largearray[4096*1024]; }; struct LargeStruct incrementCharAtOffset(struct LargeStruct s, int offset) { s.largearray[offset]++; return s; } struct LargeStruct myLargeStruct; main() { int incrementOffset = 10; printf("Value at offset %d before incrementing %d\n", incrementOffset, myLargeStruct.largearray[incrementOffset]); myLargeStruct=incrementCharAtOffset(myLargeStruct,incrementOffset); printf("Value at offset %d after incrementing %d\n", incrementOffset, myLargeStruct.largearray[incrementOffset]); }Turn-in requirement: submit your program as a file called
hw2i1b.c
in your hw2 directory, and add hw2i1b
as a target to the Makefile.
#include<stdio.h> #include<stdlib.h> #include<string.h> char reversed[1024*1024]="Huge"; int main(int argc, char** argv) { if(argc != 2) { fprintf(stderr,"Usage: hw2i2a <word>\n"); exit(1); } memset(reversed,0,sizeof(reversed)); int i; for(i=0;i<strlen(argv[1]);i++) { reversed[i]=argv[1][strlen(argv[1])-i-1]; } printf("%s = reversed(%s)\n",reversed,argv[1]); printf("The reversed string array is %ld bytes.\n",sizeof(reversed)); }Turn-in requirement: submit your program as a file called
hw2i2a.c
in your hw2 directory, and add hw2i2a
as a target to the Makefile.
concatenate()
, so that it returns the result of concatenating strings a and b. For example, concatenate("fire","cracker")
returns the string "firecracker". You'll need to use malloc()
inside concatenate. However, since there are no calls to free(), this code is leaking memory. That's ok for now.
NOTE: as before, you may not use existing string library functions, such as sprintf, strcpy, etc for this homework. strlen() is ok.
#include<stdio.h> #include<stdlib.h> #include<string.h> char *concatenate(char* a, char* b) { return a; // replace this with your string concatenation code } int main(int argc, char** argv) { if(argc<4) { printf("Usage: hw2i2b <count> <firstword> <secondword>\n"); exit(1); } char *middle="cruel"; char number[10]; int i; for(i=0;i<atoi(argv[1]);i++) { sprintf(number,"%d",i); // update the number string // begin leaky char *line = concatenate( // not leaked concatenate(argv[2],number), // leaked concatenate(middle, // leaked concatenate(number, argv[3]))); // leaked if(i>0) // can't free the statically allocated "cruel" string above free(middle); // end leaky printf("%s\n",line); middle=line; } free(middle); }Example program output:
~> ./hw2i2b 10 hello world hello0cruel0world hello1hello0cruel0world1world hello2hello1hello0cruel0world1world2world hello3hello2hello1hello0cruel0world1world2world3world hello4hello3hello2hello1hello0cruel0world1world2world3world4world hello5hello4hello3hello2hello1hello0cruel0world1world2world3world4world5world hello6hello5hello4hello3hello2hello1hello0cruel0world1world2world3world4world5world6world hello7hello6hello5hello4hello3hello2hello1hello0cruel0world1world2world3world4world5world6world7world hello8hello7hello6hello5hello4hello3hello2hello1hello0cruel0world1world2world3world4world5world6world7world8world hello9hello8hello7hello6hello5hello4hello3hello2hello1hello0cruel0world1world2world3world4world5world6world7world8world9worldTurn-in requirement: submit your program as a file called
hw2i2b.c
in your hw2 directory, and add hw2i2b
as a target to the Makefile.
malloc()ed
strings before we get a chance to free()
them.
Without resorting to much stronger measures, the only way to fix these leaks is to keep a pointer to each string until we don't need the string any more, and then free()
it. Make a copy of your hw2i2b.c, calling it hw2i2c.c. Changing only the lines between the "begin leaky" and "end leaky" comments, make sure to plug every memory leak in this program.
To help with the debugging, add the following before concatenate()
, change the malloc()
call in concatenate to mymalloc()
, and use myfree()
instead of free()
(yes, you're allowed to make those changes).
void* mymalloc(int size) { void* ptr = malloc(size); fprintf(stderr,"malloc: %p\n",ptr); return ptr; } void myfree(void* ptr) { fprintf(stderr,"free: %p\n",ptr); free(ptr); }example output:
./a.out 2 hello world malloc: 100080 malloc: 100090 malloc: 1000a0 malloc: 1000b0 free: 100080 free: 100090 free: 1000a0 hello0cruel0world malloc: 1000a0 malloc: 100080 malloc: 1000d0 malloc: 1000e0 free: 1000a0 free: 100080 free: 1000d0 free: 1000b0 hello1hello0cruel0world1world free: 1000e0Turn-in requirements: hw2i2c.c and a hw2i2c Makefile target, you know the drill.
long long fib(x) { if(x<2) return 1; else return fib(x-1)+fib(x-2); }and an iterative implementation
main() { long long back1=1,back2=1; printf("1, 1, "); int i; for(i=2;i<75;i++) { long long fib=back1+back2; printf("%lld, ",fib); back2=back1; back1=fib; } }Both solutions use the 64-bit type "long long" to support large integers. You are to implement a "reverse fibonacci series" program, in three different ways. All three programs take the same input and produce the same output:
./hw2i3a 6 8,5,3,2,1,1 ./hw2i3b 3 2,1,1 ./hw2i3c 9 34,21,13,8,5,3,2,1,1 ./hw2i3a 70 190392490709135,117669030460994,72723460248141,44945570212853,27777890035288,17167680177565,10610209857723,6557470319842,4052739537881,2504730781961,1548008755920,956722026041,591286729879,365435296162,225851433717,139583862445,86267571272,53316291173,32951280099,20365011074,12586269025,7778742049,4807526976,2971215073,1836311903,1134903170,701408733,433494437,267914296,165580141,102334155,63245986,39088169,24157817,14930352,9227465,5702887,3524578,2178309,1346269,832040,514229,317811,196418,121393,75025,46368,28657,17711,10946,6765,4181,2584,1597,987,610,377,233,144,89,55,34,21,13,8,5,3,2,1,1In our tests, the input number will always be below 75 and above 2.
hw2i3a.c
, hw2i3b.c
and hw2i3c.c
in your hw2 directory, and add the corresponding targets to the Makefile.
/usr/src/linux-2.6.37
. This directory contains the entire source code for the linux kernel, including support for dozens of hardware architectures, and thousands of peripheral devices.
Before we can build our new kernel, we need to configure it for our system. We have prepared an initial configuration for you, which you can download from here: config. Because the default configuration comes with nearly everything enabled, this stripped down config file will reduce the compile time. Place the file in your /usr/src/linux-2.6.37
and rename it to .config
.
HINT: Because some of the steps in this process take a great deal of time, it is a good idea to save the state of your virtual machine just in case a later step messes things up. From the "Virtual Machine" menu select "Take a snapshot" to save your machine's state. If something goes wrong you can then restore that state by selecting "revert to snapshot" from the "Virtual Machine" menu.
Place the .config file in the /usr/src/linux-2.6.37
directory. There are several ways to edit the config file, we will use menuconfig. In order to run menuconfig use apt-get to install the following packages: libncurses5, libncurses5-dev. Then run:
make menuconfigTurn-in requirement: Lets change the version information of this kernel to something a bit more personal. From inside menuconfig select
General setup
and then select Local version
. Type in your name here without any spaces ex: DennisRitchie
.
Later on, once you compile the kernel you will run a command that prints out the current installed kernel version and your name should be displayed.
Now that the configuration is complete it is time to perform the compilation. We start by building the kernel executable:
sudo makeThis should take about a 1/2 hour or so. Next run:
sudo make installAfter this is complete do a
ls /boot
to print out the contents of the boot directory. You should now see three files in the directory with your name on it: the kernel (starts with vmlinuz), the config file and the system map.
Next we will need to compile the loadable modules. This will take longer than the kernel compile, perhaps an hour or so. Run the following command to build the modules:
sudo make modulesOnce that finishes you will want to install the modules into the right directory using the following command:
sudo make modules_installNow we need to create an initial ram disk image. This allows us to perform the necessary work for loading up our kernel without actually having an operating system. You can read a bit about this here: initrd from wikipedia. We can use the mkinitframfs program to create the image:
sudo mkinitramfs -o /boot/initrd.img-2.6.37DennisRitchie 2.6.37DennisRitchieGRUB is the de facto bootloader for Linux. We now need to let GRUB know that we built a new kernel. The first thing we'll do with GRUB is change it's configuration file so that we force the user to have to choose a kernel before we boot. Open up the file
/etc/default/grub
and modify the GRUB_TIMEOUT
parameter to be -1
. Now we need to regenerate our grub config file. We can do this by running this command:
sudo grub-mkconfig -o /boot/grub/grub.cfgThis program finds new kernels and generate the grub.cfg configuration file, including our new timeout parameter. Now it is time to load up our kernel! This would be a great time to take a snap shot of your virtual machine! Now we will reboot the machine and see what happens.
sudo rebootSuccess! (Hopefully). Turn in requirement Take a snapshot of the VMware machine from your host machine. In the terminal window type:
uname -r
. You should see: 2.6.37DennisRitchie
. Make sure that this appears in the snapshot. Name the file kernel.png
when you submit it. I | Attachment | Action | Size | Date![]() |
Who | Comment |
---|---|---|---|---|---|---|
![]() |
config | manage | 125.1 K | 2011-01-18 - 18:40 | UnknownUser | kernel config file |
Copyright 2016 The Board of Trustees of the University of Illinois.webmaster@cs.uic.edu |
WISEST Helping Women Faculty Advance Funded by NSF | ![]() | ![]() |