Anda di halaman 1dari 42

Advanced C - Workshop

By
Madheswaran D

Version: <1.3>
Date: < 23/10/2006>
Introduction

 Pre-requisites
• Basic C knowledge (Not covered here)
• Familiarity with Unix environment (basic unix commands, user
knowledge on Vi or Emacs editors). (Not covered here)
• Alignment & Padding issues.
• Good understanding about pointers.
• Good understanding about bitwise operators

 Advanced Topics
• Handy Expressions involving bit wise operations
• Stack frames  What happens during function calls
• Variable arguments  How is it implemented?
• Dynamic memory allocation  A sample design of malloc/free

Wipro confidential 2
Alignment & Padding

 For today’s session, assume following sizes and study the following program
• Char: 1 byte
• Int: 4 bytes
• Short: 2 bytes

typedef struct
{
char name[30];
int empno;
int salary;

} EmpRec, * EmpRecPtr;

main()
{
int x = 1;
char y = 2;
int z = 3;
EmpRec abc;
EmpRecPtr empr = &abc;

printf(“Sizes: int=%d, char=%d, EmpRec=%d, EmpRecPtr=%d\n”, sizeof(x), sizeof(y),


sizeof(abc), sizeof(empr));
printf(“Address: &x=%p, &y=%p, &z=%p, &abc=%p, &empr=%p\n”, &x, &y, &z, &abc, &empr);
printf("Address: &abc.name=%p, &abc.empno=%p, &abc.salary=%p\n", &abc.name,
&abc.empno, &abc.salary); }

Wipro confidential 3
Alignment & Padding

 For today’s session, assume following sizes and study the following program
• Char: 1 byte
• Int: 4 bytes
• Short: 2 bytes Sizes: int=4, char=1, EmpRec=40, EmpRecPtr=4
typedef struct Address: &x=0xbffffb3c, &y=0xbffffb3b, &z=0xbffffb34,
{ &abc=0xbffffb00, &empr=0xbffffafc
char name[30];
Address: &abc.name=0xbffffb00,
int empno;
int salary; &abc.empno=0xbffffb20, &abc.salary=0xbffffb24

} EmpRec, * EmpRecPtr;

main()
{
int x = 1;
char y = 2;
int z = 3;
EmpRec abc;
EmpRecPtr empr = &abc;

printf(“Sizes: int=%d, char=%d, EmpRec=%d, EmpRecPtr=%d\n”, sizeof(x), sizeof(y),


sizeof(abc), sizeof(empr));
printf(“Address: &x=%p, &y=%p, &z=%p, &abc=%p, &empr=%p\n”, &x, &y, &z, &abc,
&empr);
printf("Address: &abc.name=%p, &abc.empno=%p, &abc.salary=%p\n", &abc.name,
&abc.empno, &abc.salary);}
Wipro confidential 4
Memory view

&(abc.name)
&(abc.salary) &(abc.empno
)
typedef struct b00 | | |
{ Lower | | |
char name[30]; Memory
| | |
int empno;
int salary; | | |
} EmpRec, *EmpRecPtr; | | |
| | |
main() Stack grows
{ | | |
int x = 1; this way
| | p | p b1f
char y = 2;
b20 | | |
int z = 3;
EmpRec abc; b24 | | |
b27
EmpRecPtr empr = &abc; b28 p | p | p | p
Higher p | p | p | p
printf("Sizes: int=%d, char=%d, EmpRec=%d, Memory
EmpRecPtr=%d\n", sizeof(x), sizeof(y), p | p | p | p
sizeof(abc), sizeof(empr)); 3 | 0 | 0 | 0 b37
printf("Address: &x=%p, &y=%p, &z=%p, b34
&abc=%p, &empr=%p\n", &x, &y, &z, &abc, b38 p | p | p | 2 b3b
&empr); 1 | 0 | 0 | 0 b3f
printf("Address: &abc.name=%p,
b3c
&abc.empno=%p, &abc.salary=%p\n",
&abc.name, &abc.empno, &abc.salary);
}
&z &x &y

Wipro confidential 5
Alignment & Padding

 Memory address of a variable will align with their size.


 In some architectures, unaligned access can result in SIGBUS.
• In some cases, the memory access will be split
 This is applicable for global variables, local variables,
arguments passed to function and structure/union as well.
 To ensure address is correctly aligned, padding is done. Keep
this in mind:
• To calculate the size of structure/union
• Beware if this is mapped to a set of registers.
• Assembly/C intermixing – Suitable mask & shifting may needed
• Bit fields doesn’t have such alignment requirements
• Compiler generates code with masks & shifts to handle this.

Wipro confidential 6
SIGBUS or SPLIT ACCESS EXAMPLE

main()
{
char x = 10;
char y = 20;
int *p = &y;
printf(“&y=%p &p=%p\n”, &y, &p);
printf(“%d\n”, (*p) & 0xff); /* SIGBUS or unaligned split access */
}

Wipro confidential 7
Alignment & Padding

 Assume a H/W device is memory mapped on the system bus


• Occupies a address space of 16 bytes where 8 registers are located
• Three 32 bit Registers(CNTL1, CNTL2, CNTL3, in that order)
• Four 8 bit Registers(STAT1, STAT2, STAT3, and ERR in that order)
• Assume it is located at 0x2000 in the memory map
• A structure can be defined to map this
struct hw_device {
unsigned int cntl1;
unsigned int cntl2;
unsigned int cntl3;
unsigned char stat1;
unsigned char stat2;
unsigned char stat3;
unsigned char err;
} *my_hw_device;

my_hw_device_ptr = (struct hw_device *) (0x2000);


The registers can be accessed as my_hw_device->cntl1, my_hw_device->err and so on.
Simplifies access to device registers, useful to device driver writers, OS developers .
• Should be careful about any padding for alignment restrictions

Wipro confidential 8
Example – Where padding causes trouble

Register sequence:
Two 32 bit Registers(CNTL1, CNTL2, in that order)
Three 8 bit Registers(STAT1, STAT2, STAT3, in that order)
One 32 bit register CNTL3
One 8 bit register ERR
Bad structure that can cause trouble:
typedef struct hw_device {
unsigned int cntl1;
unsigned int cntl2;
unsigned char stat1;
unsigned char stat2;
unsigned char stat3;
unsigned int cntl3;
unsigned char err;
} MYDEVICE, *MYDEVICE_PTR;

Wipro confidential 9
Pointers – Basics

 Pointer holds address of a variable.


int x = 10;
int *p = &x;
printf(“&x=%p, p=%p, x=%d, *p=%d\n”, &x, p, x, *p);
• Output:
&x=0x22cce4, p=0x22cce4, x=10, *p=10
 Then why do you need a pointer?
& cannot be used as a “lvalue”
&x = p; /* this is not a legal statement */
 Even const pointers doesn’t have lvalue
Int * const p = x;
p = p + 1; /* illegal statement */

const int *p = x;
*p = 10; /* illegal statement */
 Arrays and Pointers
char a[10]=“Hello”;
char *str = a;
int b[10];
Int *intp = b;
printf(“%s %s\n”, a, str);
printf(“%c %c %c %c\n”, a[1], str[1], 1[str], 1[a]);
printf(“%p %p %p %p\n”, a, str, &a[1], str+1);
printf(“%p %p %p %p\n”, b, intp, &b[1], intp+1);
Output:
Hello Hello
eeee
0x22ccd0 0x22ccd0 0x22ccd1 0x22ccd1
 Then pointers and arrays be interchangeably used?
• Yes and No.

Wipro confidential 1
Pointers – Basics

 Arrays and Pointers


char a[10]=“Hello”;
char *str = a;
printf(“%d %d %d\n”, sizeof(a), sizeof(str), strlen(a));
• Output:
10 4 5
 Double Dimension arrays and double pointers
main()
{
char a[5][10]={"One", "Two", "Three", "Four", "Five" };
char **str = a;
char *b[5]={"One", "Two", "Three", "Four", "Five" };
char **str1 = b;
printf("%d %d %d %d\n", sizeof(a), sizeof(str), sizeof(b), sizeof(str1));
printf("%p %p %p %p %p %p\n", a, str, &a[1], &str[1], &a[1][1], &str[1][1]);
printf("%p %p %p %p %p %p\n", b, str1, &b[1], &str1[1], &b[1][1], &str1[1][1]);
}
• Output:
50 4 20 4
0x22cca0 0x22cca0 0x22ccaa 0x22cca4 0x22ccab 0x1
0x22cc60 0x22cc60 0x22cc64 0x22cc64 0x403005 0x403005

Wipro confidential 1
Pointers – Basics

 Arrays and Pointers


char a[10]=“Hello”; a[1]: Second Str points to a
char *str = a; dimension size of a pointer.&str[1] is
printf(“%d %d %d\n”, sizeof(a), is 10 and hence 10 str+1 and since
sizeof(str), strlen(a)); is added. size of a pointer is
• Output: 4 bytes, str + 1
10 4 5 translates to
 Double Dimension arrays and double pointers 0x22cca0 + 4
main()
{
char a[5][10]={"One", "Two", "Three", "Four", "Five" }; Add 1 to a[1]
char **str = a;
20: char *b[5]={"One", "Two", "Three", "Four", "Five" };
because it char **str1 = b;
is array of printf("%d %d %d %d\n", sizeof(a), sizeof(str), sizeof(b), sizeof(str1));
5 pointers printf("%p %p %p %p %p %p\n", a, str, &a[1], &str[1], &a[1][1], &str[1][1]);
printf("%p %p %p %p %p %p\n", b, str1, &b[1], &str1[1],
&b[1][1], &str1[1][1]); &str[1][1] translate to
&(*(*(str+4) + 1)), i.e
}
&(*(*(0x22cca4) + 1))).
• Output:
50 4 20 4
0x22cca0 0x22cca0 0x22ccaa 0x22cca4 0x22ccab 0x1 This is equal to
0x22cc60 0x22cc60 0x22cc64 0x22cc64 0x403005 0x403005 &(*(0 + 1)) and is
equal to 1 and str[1][1]
will be a junk value
Wipro confidential 1
Pointer Basics

&str1[0][0] b

&str[0][0]
0 1 2 3 4 5 6 7 8 9
a[0] O n e \0 b[0] One\0
a[1] T w o \0 b[1] Two\0
a[2] T h r e e \0 b[2] Three\0
a[3] F o u r \0 b[3] Four\0
b[4] Five\0
a[4] F i v e \0

&str[1][1] translates to
&(*(*(str+4byte) + 1)),
i.e &(*(*(0x22cca4) +
1))). This is equal to str1[1][0]=
&(*(0 + 1)) and is equal str1[1]=*(s str1[1][1]
to 1. So str[1][1] will be tr1 + *(*(str1+4byte
a junk value 4byte) s)+0) = T
Wipro confidential 1
Pointer Basics

a b
Junk\0

0 1 2 3 4 5 6 7 8 9
a[0] O n e \0 b[0] One\0

a[1] T w o \0 b[1] Two\0

a[2] T h r e e \0 b[2] Three\0


b[3] Four\0
a[3] F o u r \0
b[4] Five\0
a[4] F i v e \0

char *temp = “junk”; char *temp= “junk”;


a[0]=temp; b[2] = temp;

Wipro confidential 1
Pointers – Arithmetic & Casting

typedef struct
{
int day;
ef be ad de ee ff c0 00 ‘a’ ‘b’ ‘c’ ‘d’ ‘e’ 0 0 0 1f ca af de de ca 0 0 1 0 0 0
int month;
int year;
} Date;
all
cp+1 sp+1 ip+1cp+5 sp+3 ip+2 dp+1 dp+2
ip + 3 ip + 6
int abc=0xdeadbeef; sp + 8 sp + 16
int def=0xc0ffee;
char ghi[6]=“abcde”; cp + 12 cp + 24
int jkl = 0xdeafca1f;
short mno = 0xcade;
Date pqr = { 1, 1, 2006 }; • When a pointer is incremented by 1, depending upon
the type, number of bytes moved will defer.
main()
{
int *ip = &abc;
• When casting from one type to another
short *sp = (short *)&abc;
char *cp = (char *) &abc; • Take care alignment issues (SIGBUS)
Date *dp = (Date *) &abc;
…….. • Keep in mind that number of bytes that will move
}
for every increment/decrement will change.
Note: Little endian architecture assumed

Wipro confidential 1
Pointers – Function pointers

 Pointers can point to functions as well in addition to variables.


• Declaration example: int (*f1)(int,char **) -> Pointer to a function that returns int and
takes one integer and one char double pointer as arguments.
• Assignment example: f1=main;
 All the pointer arithmetic, casting, etc is applicable function pointers also.
void * fast_algo(int size);
void * mid_algo(int size);
void * slow_algo(int size);
typedef enum { HIGHSPEED_HIGHMEM, MIDSPEED_MIDMEM, LOWSPEED_LOWMEM } ALGO_CLASS;
ALGO_CLASS x;
void* (*MemAllocAlgo[3])(int) = { fast_algo, mid_algo, slow_algo};
void* (*MyAlloc)(int);
void AssignAllocator(ALGO_CLASS user_choice)
{

void* (**TempMyAlloc)(int);
TempMyAlloc = MemAllocAlgo;

MyAlloc = MemAllocAlgo[user_choice];
/* Alternate1: MyAlloc= TempMyAlloc[user_choice]
Alternate 2: MyAlloc = *(TempMyAlloc + user_choice) */
}

Wipro confidential 1
Volatile pointers

 Volatile keywords informs compiler that optimisations must be disabled for that
variable.
 The following code has a problem. Compiler will not generate code for
disabling interrupt.

#define BASE_ADDRESS 0x80808000


#define INTERRUPT_REGISTER_OFFSET 0x10
CriticalSection()
{
int *intr_reg = (BASE_ADDRESS + INTERRUPT_REGISTER_OFFSET);
*(intr_reg) = 1; /* disables interrupt */
/* critical code, interrupt must be disabled here */
…….
…….
/* critical code is executed, interrupt can be enabled here */
*(intr_reg) = 0; /* enables interrupt */
}

 The problem can be solved simply by defining intr_reg as volatile:


volatile int *intr_reg = (BASE_ADDRESS + INTERRUPT_REGISTER_OFFSET);

Wipro confidential 1
Think about this – Volatile & Constant together

 Can constant and volatile be used together during a


declaration?
 Example:
• volatile int * const p = 0xc8000000;

Wipro confidential 1
Bit Manipulations

main()
{
int x = -10;
printf(“%d\n”, ~x+1);
}

main()
{
unsigned int x = 5;
while(--x >= 0)
{
printf(“Hello World\n”);
}
}

Wipro confidential 1
Bit Manipulations

main()
Output: 10
{
~x represents one’s compliment of x.
int x = -10;
~x+1 represents two’s compliment of x. (i.e
printf(“%d\n”, ~x+1); negative of x)
}

main()
{ HelloWorld is printed infinitely.
unsigned int x = 5; X becomes MAXINT when it is decremented
while(--x >= 0) while it is having a value of 0.
{
printf(“Hello World\n”);
}
}

Wipro confidential 2
Arithmetic and Logical Shifts

main() Output: 0xC0000000


{ Signed number, “sign extension” happens
int x = 0x80000000; for right shift. (Arithmetic shift)
printf(“%x\n”, x >> 1);
}

main()
{
unsigned int x = 0x80000000;
printf(“%x\n”, x >> 1); Output: 0x40000000
} Unsigned number, “sign extension”
doesn’t happen for right shift. (Logical shift)

Wipro confidential 2
Advanced Topics

 Handy Bitwise Expressions


 Stack frames  What happens during function calls
 Variable arguments  How is it implemented?
 Dynamic memory allocation  How can it be implemented?

Wipro confidential 2
Handy Bitwise Expressions

Expression Purpose Remarks


1 X&1 Check whether number All numbers are interms of 0’s and 1’s and
is odd or even hence it is sufficient check the last bit
2 X << 1 Multiply by 2

3 X >> 1 Divide by 2

4 ~X+1 Negative the number Negative numbers are represented by two


complement. (one’s complement +1)
5 X ^ all’ones Bit toggling (equivalent
to ~)
6 X >> 31 To find out the sign of Result is 0 or -1 based on the sign.
the number of X
7 Mask = X >> 31 ABS(X) without using Mask contains all zeros if X is positive and
Result = (~Mask & X) | (Mask & (-X)) comparisions all ones if X is negative.

8 Mask = (X-Y) >> 31 Min(X, Y) without using Mask contains all zeros if Y is less than or
Result = (Mask & X) | (~Mask & Y) comparisions equal to X and all ones if X is less than Y.

9 Mask = (X-Y) >> 31 Max(X, Y) without using Mask contains all zeros if X is greater than
Result = (Mask & Y) | (~Mask & X) comparisions or equal to Y and all ones if Y is greater
than X.

Wipro confidential 2
Exercise 1: Power of 2.

 Come up with an “handy” expression that can be used to


detect whether the given number is a power of 2.
 Clue: All number that is a power of 2 will have just one bit set.
• Examples:
• 1 – 00000001
• 2 – 00000010
• 4 – 00000100
• 8 – 00001000
• 16- 00010000
• 32 -00100000

Wipro confidential 2
X86 Stack view during function calls in C

Sample program:
/* assuming EBP as a integer pointer */ ESP
int f2(int x1, int y1) /* x1 is *(EBP+2), y1 *(EBP + 3) */
{ Saved regs in f2
int l5 = 110; /* l5 is *(EBP – 1), l6 is *(EBP -2) */ l6
int l6 = 120; l5
Lower EBP
Memory Prev Frame Ptr
return (0)
Ret addr in f1
} x1
y1

int f1(int x, int y) Stack grows Saved regs in f1


{ l4
int l3 = 50; this way
l3
int l4 = 60;
Prev Frame Ptr
return f2(l3 + x, l4 + y);
/* right most argument pushed to stack first */ Ret addr in main
x
} Higher y
main() Memory Saved regs in main
{
int l1 = 10; l3
int l2 = 20; l2
int l3 = f1(l1 + 20, l2 + 20); l1
}
Prev Frame Ptr

Wipro confidential 2
Scope – Check your understanding now

 Is scope of global and static variables clear?


 Following code is sequence is perfectly legal. How is it handled?
f1(int x, int y)
{
int abc = 0xdeadbeef;

printf(“%x\n”, abc);

{
int abc = 0xc0ffee;
int x = 0x100;
printf(“%x\, %xn”, abc, x);
}
}
(Clue: Local variables can get into stack or register)

Wipro confidential 2
Function Arguments – Check your understanding
now

 A new function named “File1Func1” is implemented in file1


 Prototype of the function is as follows
• Int File1Func1();
 In file1, the function is implemented as follows:
Int
File1Func1(int x, int y)
{
…..
}

 In file2, this function is called as follows.


File1Func1(10,20,30);
 File1Func1 is called with 3 arguments, while the
implementation takes only two arguments. What will happen
now?

Wipro confidential 2
Exercise 2: Stack tracing

 You have a.o file and have a.h and b.h


 a.h contents are:
• extern int func1(int x, int y);
• extern int func2(int x, int y);
 b.h contents are
• extern int func3(int x, int y);
 Given that calling sequence is:
• Main->func1->func2->func3
 You got to implement b.c that has function func3
• func3 should print value of x passed to func1.

Wipro confidential 2
Security issue – Buffer Overflow on stack

main(int argc, char *argv[])


{
int flag;
char filename[16];

if (argc != 2)
{
fprintf(stderr, "Usage: %s filename\n", argv[0]);
exit(1);
}
….
flag = check_permission();

strcpy(filename, argv[1]); /* Depending upon argv[1], the return address could get corrupted */
........
if (flag == 0xdeadbeef)
{
/* execute the as root or deposit million dollars in a bank account */
}
else
{
/* execute the program as normal user, deduct $10 from an account */.
}

}
/* clever hacker will manage the argv[1] such that return address is changed to a desired location. Or he can change the value of
flag */
/* typically entire binary program of “undesired program” is also passed as an argument, along with return address change */

Wipro confidential 2
Variable arguments in C

 va_start(ap, num_args)  Typically implemented as macro, just


initializes ap such that it points to first un-named argument. (It
will use frame pointer + offset of second argument from fp to
iniatialize ap)
 va_arg(ap, type)  Returns an argument & updates ap
 va_end(ap)  Implementation specific cleanups.

 Number of arguments should be known directly or indirectly


• main: argc is the first argument that will tell number of arguments
• Printf: number of arguments are indirectly found from number of %
in format argument
 Type of the arguments should be known
• main: Strings (char *argv[])
• printf: character following % tells the argument type

Wipro confidential 3
Exercise 3: MyPrintf Implementation

 Implement myprintf(char *fmt, …) function


 Handle %d, %x, %c and %s types in fmt string.
 You can use putchar function to output a character on to the
screen.
 If you use any other C library function, you must implement
them as well.

Wipro confidential 3
Dynamic Memory allocation -- Internals

 Dynamic memory allocation


• Memory allocated from heap
 In unix,
• heap typically comes after BSS area
• Brk call is used to change the “data segment” memory allocated to a process
 Each memory allocation needs additional overhead memory that is also taken
from heap.
 Typical implementation, each allocation preceded by MCB (Memory control
Blocks)
 MCB structure
struct MCB
{
int is_available;
int size;
};

 Many approaches are there. Serious research topic.


• Space efficiency: Requested vs Allocated, Number of chunks
• Speed: How quickly malloc/free can be executed. Critical in RTOS.

Wipro confidential 3
Dynamic Memory Allocation

Main()
Heap Start {
ptr1
MCB 1: 0, 108 char *ptr1 = malloc(100);
Allocation 1
char *ptr2 = malloc(200);
MCB 2: 0, 208 ptr2 Control
Last allocation Allocation 2 …….
Free Memory free(ptr1);
….
ptr1 = malloc(300);
Heap End ….
free(ptr1)
….
Note:
ptr1 = malloc(50);
When 100 bytes are requested, actually 100 bytes +
sizeof(MCB) has been utilized. MCB is the overhead. ….

free(ptr1);
free(ptr2);
}
Wipro confidential 3
Dynamic Memory Allocation

Main()
Heap Start {
MCB 1: 1, 108 char *ptr1 = malloc(100);
Allocation 1
char *ptr2 = malloc(200);
MCB 2: 0, 208 ptr2

Allocation 2 …….
MCB 3: 0, 308 free(ptr1);
ptr1
Last allocation Allocation 3
….
Free Memory
ptr1 = malloc(300);
Control
Heap End ….
free(ptr1)
….
Note:
ptr1 = malloc(50);
free doesn’t take size as the the argument. It is
calculated by accessing *(ptr1 – sizeof(MCB) + ….
sizeof(int))
MCB1 & allocation 1 remains intact even though it is
free(ptr1);
not allotted.
free(ptr2);
}
Wipro confidential 3
Dynamic Memory Allocation

Main()
Heap Start {
ptr1
MCB 1: 0, 108 char *ptr1 = malloc(100);
Allocation 1
char *ptr2 = malloc(200);
MCB 2: 0, 208 ptr2

Allocation 2 …….
MCB 3: 1, 308 free(ptr1);
Last allocation
Allocation 3
….
Free Memory
ptr1 = malloc(300);
Heap End ….
free(ptr1)
….
Note:
ptr1 = malloc(50);
First allocation is re-utilised. That is 100 bytes are
allocated, when 50 bytes are requested. Control ….

free(ptr1);
free(ptr2);
}
Wipro confidential 3
Dynamic Memory Allocation

Main()
Heap Start {
MCB 1: 1, 108 char *ptr1 = malloc(100);
Allocation 1
char *ptr2 = malloc(200);
MCB 2: 1, 208
Allocation 2 …….
Last allocation MCB 3: 1, 308 free(ptr1);
Allocation 3
….
Free Memory
ptr1 = malloc(300);
Heap End ….
free(ptr1)
….
ptr1 = malloc(50);
….

free(ptr1);
Control
free(ptr2);
}
Wipro confidential 3
Pros & cons of MCB approach

 Simple and Very fast


 MCB overhead per allocation
 Allocation based on first match, rather than best match. (100
bytes allocated, instead of 50 bytes)
• ptr1=malloc(1024 * 1024); free(ptr1), ptr1=malloc(10); we would
allocate 1MB for 10 bytes.
• Improvements: free space could divided into chunks of fixed size.
(typically in power of 2). This would limit the wastage.
 In case of alignment issues, attach the excess bytes to
previous MCB.
 Doesn’t create new chunks, unless all previous allocated
chunks are used. Less fragmentation.

Wipro confidential 3
Rainy day scenarios – What happens now?

1. Lost memory
ptr1=malloc(100);
ptr1=malloc(200);
2. Double free
ptr1=malloc(100);
free(ptr1);
free(ptr1);
3. Accessing memory after free
ptr1=malloc(10);
free(ptr1)
*(ptr1+9) = ‘\0’’;
4. Out of range access
ptr1=malloc(10);
*(ptr1+10) = ‘\0’;

Wipro confidential 3
Exercise 4: Implement myalloc & myfree functions

 Requirements:
• You should not use any of the existing C or C++ library calls for memory
alloc (malloc, calloc, realloc, new, etc…)
• Implement void *myalloc(int elem_size) and void free(void *p);
• You also have to implement void InitMem(char *ptr, int size_in_bytes)
• Through this interface, one big chunk of memory will be provided to you.
• Use the part of these memory in further calls of myalloc & myfree functions.
• You also have to implement int MemEfficiency() that returns number of
MCBs (chunks) present.
• If you are adventurous, address following aspects
• Minimize the fragmentation by joining adjacent free blocks
• Put a time limit towards myalloc and myfree functions.
• Make it thread safe. 
• Allocated memory should align with the size requested. Example: myalloc(10)
means the pointer returned must be divisible by 10.

Wipro confidential 3
Security issue – buffer overflow on heap

main(int argc, char *argv[])


{

char *filename_p;

if (argc != 2)
{
fprintf(stderr, "Usage: %s filename\n", argv[0]);
exit(1);
}
filename_p = malloc(1024);

strcpy(filename, argv[1]); /* Depending upon argv[1], MCBs or even other areas can get
corrupted */

....
}

Wipro confidential 4
Security issues – Be aware

 We need to write defensive program to escape security attacks


• Know length of a string before you copy.
• A defence mechanism needed before using any size related
information coming across network.
• Beware of DOS attacks.
• If you write a server program, beware not to accept too many
connections from same client in a short period.

Wipro confidential 4
Thank you.

Information contained and transmitted by this presentation is proprietary to Wipro Limited and is intended for use only by the individual or entity to which it is addressed,
and contains information that is privileged, confidential or exempt from disclosure under applicable law.

Wipro confidential 4

Anda mungkin juga menyukai