broken.c
/**
* @file broken.c
* @author mmalensek
*
* This program contains a series of buggy, broken, or strange C functions for
* you to ponder. Your job is to analyze each function, fix whatever bugs the
* functions might have, and then explain what went wrong. Sometimes the
* compiler will give you a hint.
*
* ____________
* < Good luck! >
* ------------
* \ ^__^
* \ (oo)\_______
* (__)\ )\/\
* ||----w |
* || ||
*/
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
static int func_counter = 1;
#define FUNC_START() printf("\n\n%d.) %s\n", func_counter++, __func__);
/**
* This awesome code example was taken from the book 'Mastering C Pointers,'
* one of the famously bad resources on learning C. It was trying to demonstrate
* how to print 'BNGULAR'... with pointers...? Maybe?
*
* (1) Fix the problem.
* (2) Explain what's wrong with this code:
* Hint: where are string literals stored in memory?
* Hint: what is '66' in this example? Can we do better?
*/
void
angular(void)
{
FUNC_START();
char *a;
a = "ANGULAR";
*a = 66;
printf("%s\n", a);
}
/**
* This function is the next step after 'Hello world' -- it takes user input and
* prints it back out! (Wow).
*
* But, unfortunately, it doesn't work.
*
* (1) Fix the problem.
* (2) Explain what's wrong with this code:
*
* (answer)
*/
void
greeter(void)
{
FUNC_START();
char *name = 0;
printf("Please enter your name: ");
gets(name, 128);
// Remove newline character
char *p = name;
for ( ; *p != '\n' && *p != 0; p++) { }
*p = '\0';
printf("Hello, %s!\n", name);
}
/**
* This 'useful' function prints out an array of integers with their indexes, or
* at least tries to. It even has a special feature where it adds '12' to the
* array.
*
* (1) Fix the problem.
* (2) Explain what's wrong with this code:
*
* (answer)
*/
void
displayer(void)
{
FUNC_START();
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Waggressive-loop-optimizations"
int stuff[100] = { 0 };
/* Can you guess what the following does without running the program? */
/* Rewrite it so it's easier to read. */
14[stuff + 1] = 12;
for (int i = 0; i < 1000; ++i) {
printf("%d: %d\n", i, stuff[i]);
}
#pragma GCC diagnostic pop
}
/**
* Adds up the contents of an array and prints the total. Unfortunately the
* total is wrong! See main() for the arguments that were passed in.
*
* (1) Fix the problem.
* (2) Explain what's wrong with this code:
*
* (answer)
*/
void
adder(int *arr)
{
FUNC_START();
int total = 0;
for (int i = 0; i < sizeof(arr); ++i) {
total += arr[i];
}
printf("Total is: %d\n", total);
}
/**
* This function is supposed to be somewhat like strcat, but it doesn't work.
*
* (1) Fix the problem.
* (2) Explain what's wrong with this code:
*
* (answer)
*/
char *
suffixer(char *a, char *b)
{
FUNC_START();
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdangling-pointer"
char buf[128] = { 0 };
char *buf_start = buf;
strcpy(buf, a);
strcpy(buf + strlen(a), b);
return buf_start;
#pragma GCC diagnostic pop
}
/**
* This is an excerpt of Elon Musk's Full Self Driving code. Unfortunately, it
* keeps telling people to take the wrong turn. Figure out how to fix it, and
* explain what's going on so Elon can get back to work on leaving Earth for
* good.
*
* (1) Fix the problem.
* (2) Explain what's wrong with this code:
*
* (answer)
*/
void
driver(void)
{
FUNC_START();
char street1[8] = { "fulton" };
char street2[8] = { "gomery" };
char street3[8] = { "piedmont" };
char street4[8] = { "baker" };
char street5[8] = { "haight" };
if (strcmp(street1, street2)) {
char *new_name = "saint agnew ";
memcpy(street4, new_name, strlen(new_name));
}
printf("Welcome to TeslaOS 0.1!\n");
printf("Calculating route...\n");
printf("Turn left at the intersection of %s and %s.\n", street5, street3);
}
/**
* This function tokenizes a string by space, sort of like a basic strtok or
* strsep. It has two subtle memory bugs for you to find.
*
* (1) Fix the problem.
* (2) Explain what's wrong with this code:
*
* (answer)
*/
void
tokenizer(void)
{
FUNC_START();
char *str = "Hope was a letter I never could send";
char *line = malloc(strlen(str));
char *c = line;
strcpy(line, str);
while (*c != '\0') {
for ( ; *c != ' ' && *c != '\0'; c++) {
// find the next space (or end of string)
}
*c = '\0';
printf("%s\n", line);
line = c + 1;
c = line;
}
free(line);
}
/**
* This function should print one thing you like about C, and one thing you
* dislike about it. Assuming you don't mess up, there will be no bugs to find
* here!
*/
void
finisher(void)
{
FUNC_START();
// TODO
// printf( ... );
// printf( ... );
}
int
main(void)
{
printf("Starting up!");
angular();
greeter();
displayer();
int nums[] = { 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 };
adder(nums);
char *result = suffixer("kayak", "ing");
printf("Suffixed: %s\n", result);
driver();
tokenizer();
finisher();
return 0;
}