Sams Teach Yourself C in 24 Hours (47 page)

BOOK: Sams Teach Yourself C in 24 Hours
2.14Mb size Format: txt, pdf, ePub

OUTPUT
Use malloc() to allocate memory.

The purpose of the program in Listing 17.1 is to use the malloc() function to
ANALYSIS
allocate a piece of memory space that has the same size as a character string.

Then, the content of the string is copied to the allocated memory referenced by the pointer returned from the malloc() function. The content of the memory is displayed on the screen to prove that the memory space does contain the content of the string after the allocation and duplication.

Note that two more header files, stdlib.h and string.h, are included in lines 3 and 4, respectively, for the functions malloc() and strlen(), which are called in line 14.

Line 10 declares a char array, str, that is initialized with a character string of “Use malloc() to allocate memory.”. A char pointer variable, ptr_str, is declared in line 11.

The statement in line 14 allocates a memory space of strlen(str)+1 bytes by calling the malloc() function. Because the strlen() function does not count the null character at the end of a string, adding 1 to the value returned by strlen(str) gives the total number of bytes that need to be allocated. The value of the returned pointer is assigned to the char pointer variable ptr_str after the malloc() function is called in line 14.

The if-else statement in lines 15–24 checks the returned pointer from the malloc() function. If it’s a null pointer, an error message is printed out, and the return value of the main() function is set to 1 in lines 22 and 23. (Remember that a nonzero value returned by the return statement indicates an abnormal termination.)

22 067231861x CH17 1/25/00 10:19 AM Page 283

Allocating Memory

283

But if the returned pointer is not a null pointer, the start address of the str array and the pointer ptr_str are passed to a function called StrCopy() in line 16. The StrCopy() function, whose definition is given in lines 28–35, copies the content of the str array to the allocated memory pointed to by ptr_str. Then, the printf() call in lines 17 and 18

prints out the copied content in the allocated memory. Line 19 sets the return value to 0

after the success of the memory allocation and string duplication.

The output on my screen shows that a piece of memory has been allocated and that the string has been copied to the memory.

There is a potential problem if you keep allocating memory, because there is always a limit. You can easily run out of memory when you just allocate memory without ever releasing it. In the next section, you’ll learn how to use the free() function to free up memory spaces allocated for you when you don’t need them anymore.

17

Releasing Allocated Memory with
free()

Because memory is a limited resource, you should allocate an exactly sized piece of memory right before you need it, and release it as soon as you are through using it.

The program in Listing 17.2 demonstrates how to release allocated memory by calling the free() function.

TYPE

LISTING 17.2

Using the free() and malloc() Functions Together

1: /* 17L02.c: Using the free() function */

2: #include

3: #include

4: /* function declarations */

5: void DataMultiply(int max, int *ptr);

6: void TablePrint(int max, int *ptr);

7: /* main() function */

8: main()

9: {

10: int *ptr_int, max;

11: int termination;

12: char key = ‘c’;

13:

14: max = 0;

15: termination = 0;

16: while (key != ‘x’){

17: printf(“Enter a single digit number:\n”);

continues

22 067231861x CH17 1/25/00 10:19 AM Page 284

284

Hour 17

LISTING 17.2

continued

18: scanf(“%d”, &max);

19:

20: ptr_int = malloc(max * max * sizeof(int)); /* call malloc() */

21: if (ptr_int != NULL){

22: DataMultiply(max, ptr_int);

23: TablePrint(max, ptr_int);

24: free(ptr_int);

25: }

26: else{

27: printf(“malloc() function failed.\n”);

28: termination = 1;

29: key = ‘x’; /* stop while loop */

30: }

31: printf(“\n\nPress x key to quit; other key to continue.\n”);

32: scanf(“%s”, &key);

33: }

34: printf(“\nBye!\n”);

35: return termination;

36: }

37: /* function definition */

38: void DataMultiply(int max, int *ptr)

39: {

40: int i, j;

41:

42: for (i=0; i

43: for (j=0; j

44: *(ptr + i * max + j) = (i+1) * (j+1);

45: }

46: /* function definition */

47: void TablePrint(int max, int *ptr)

48: {

49: int i, j;

50:

51: printf(“The multiplication table of %d is:\n”,

52: max);

53: printf(“ “);

54: for (i=0; i

55: printf(“%4d”, i+1);

56: printf(“\n “);

57: for (i=0; i

58: printf(“----”, i+1);

59: for (i=0; i

60: printf(“\n%d|”, i+1);

61: for (j=0; j

62: printf(“%3d “, *(ptr + i * max + j));

63: }

64: }

22 067231861x CH17 1/25/00 10:19 AM Page 285

Allocating Memory

285

Whilethe executable 17L02.exe is being run, I enter two integers, 4 and 2 (highlighted in the following output), to obtain a multiplication table for each; then I quit running the program by pressing the x key:

Enter a single digit number:

OUTPUT
4

The multiplication table of 4 is:

1 2 3 4

---------------

1| 1 2 3 4

2| 2 4 6 8

3| 3 6 9 12

4| 4 8 12 16

Press x key to quit; other key to continue.

C

Enter a single digit number:

2

17

The multiplication table of 2 is:

1 2

-------

1| 1 2

2| 2 4

Press x key to quit; other key to continue.

x

Bye!

The purpose of the program in Listing 17.2 is to build a multiplication table
ANALYSIS
based on the integer given by the user. The program can continue building multiplication tables until the user presses the x key to quit. The program also stops execution if the malloc() function fails.

To show you how to use the free() function, the program allocates temporary memory storage to hold the items of a multiplication table. As soon as the content of a multiplication table is printed out, the allocated memory is released by calling the free() function.

Lines 5 and 6 declare two functions, DataMultiply() and TablePrint(), respectively.

The former is for performing multiplication and building a table, whereas the latter prints out the table on the screen. The definitions of the two functions are given in lines 38–45

and lines 47–64, respectively.

Inside the main() function, there is a while loop in lines 16–33 that keeps asking the user to enter an integer number (see lines 17 and 18) and then builds a multiplication table based on the integer.

To hold the result of the multiplication, the statement in line 20 allocates a memory storage that has the size of max*max*sizeof(int), where the int variable max contains the 22 067231861x CH17 1/25/00 10:19 AM Page 286

286

Hour 17

integer value entered by the user. Note that the sizeof(int) expression gives the byte size of the int data type for the computer on which the program is being run.

If the malloc() function returns a null pointer, the return value of the main() function is set to 1 to indicate an abnormal termination (see line 28), and the while loop is stopped by assigning the key variable with ‘x’ in line 29.

Otherwise, if the malloc() function allocates memory storage successfully, the DataMultiply() function is called in line 22 to calculate each multiplication. The results are saved into the memory storage pointed to by the ptr_int pointer. Then the multiplication table is printed out by calling the TablePrint() function in line 23.

As soon as I no longer need to keep the multiplication table, I call the free() function in line 24 to release the allocated memory storage pointed by the ptr_int pointer.

If I did not release the memory, the program would take more and more memory as the user keeps entering integer numbers to build more multiplication tables. Eventually, the program would either crash the operating system or be forced to quit. By using the free() and malloc() functions, I am able to keep running the program by taking the exact amount of memory storage I need, no more and no less.

The
calloc()
Function

Besides the malloc() function, you can also use the calloc() function to allocate memory storage dynamically. The differences between the two functions are that the latter takes two arguments and that the memory space allocated by calloc() is always initialized to 0. There is no such guarantee that the memory space allocated by malloc() is initialized to 0.

The syntax for the calloc() function is

AX

#include

void *calloc(size_t nitem, size_t size);

YNTS
Here nitem is the number of items you want to save in the allocated memory space. size

,

,

gives the number of bytes that each item takes. The calloc() function returns a void pointer too.

If the calloc() function fails to allocate a piece of memory space, it returns a null pointer.

Listing 17.3 contains an example of using the calloc() function. The initial value of the memory space allocated by calloc() is printed out.

22 067231861x CH17 1/25/00 10:19 AM Page 287

Allocating Memory

287

TYPE

LISTING 17.3

Using the calloc() Function

1: /* 17L03.c: Using the calloc() function */

2: #include

3: #include

4: /* main() function */

5: main()

6: {

7: float *ptr1, *ptr2;

8: int i, n;

9: int termination = 1;

10:

11: n = 5;

12: ptr1 = calloc(n, sizeof(float));

13: ptr2 = malloc(n * sizeof(float));

14: if (ptr1 == NULL)

17

15: printf(“malloc() failed.\n”);

16: else if (ptr2 == NULL)

17: printf(“calloc() failed.\n”);

18: else {

19: for (i=0; i

20: printf(“ptr1[%d]=%5.2f, ptr2[%d]=%5.2f\n”,

21: i, *(ptr1 + i), i, *(ptr2 + i));

22: free(ptr1);

23: free(ptr2);

24: termination = 0;

25: }

26: return termination;

27: }

The following output appears on the screen after running the executable program 17L03.exe.

ptr1[0] = 0.00, ptr2[0] = 7042.23

OUTPUT
ptr1[1] = 0.00, ptr2[1] = 1427.00

ptr1[2] = 0.00, ptr2[2] = 2787.14

ptr1[3] = 0.00, ptr2[3] = 0.00

ptr1[4] = 0.00, ptr2[4] = 5834.73

The purpose of the program in Listing 17.3 is to use the calloc() function to
ANALYSIS
allocate a piece of memory space. To prove that the calloc() function initializes the allocated memory space to 0, the initial values of the memory are printed out. Also, another piece of memory space is allocated by using the malloc() function, and the initial values of the second memory space are printed out too.

As you see in line 12, the calloc() function is called with two arguments passed to it: the int variable n and the sizeof(float) expression. The float pointer variable ptr1 is assigned the value returned by the calloc() function.

22 067231861x CH17 1/25/00 10:19 AM Page 288

288

Hour 17

Likewise, the malloc() function is called in line 13. This function only takes one argument that specifies the total number of bytes that the allocated memory should have. The value returned by the malloc() function is then assigned to another float pointer variable, ptr2.

From lines 12 and 13, you can tell that the calloc() and malloc() functions actually plan to allocate two pieces of memory space with the same size.

The if-else-if-else statement in lines 14–25 checks the two values returned from the calloc() and malloc() functions and then prints out the initial values from the two allocated memory spaces if the two return values are not null.

I ran the executable program of Listing 17.3 several times. Each time, the initial value from the memory space allocated by the calloc() function was always 0. But there is no such guarantee for the memory space allocated by the malloc() function. The output shown here is one of the results from running the executable program on my machine.

You can see that there is some “garbage” in the memory space allocated by the malloc() function. That is, the initial value in the memory is unpredictable. (Sometimes, the initial value in a memory block allocated by the malloc() function happens to be 0. But it is not guaranteed that the initial value is always zero each time the malloc() function is called.)

The
realloc()
Function

The realloc() function gives you a means to change the size of a piece memory space allocated by the malloc() function, the calloc() function, or even realloc() itself.

The syntax for the realloc() function is

AX

#include

void *realloc(void *block, size_t size);

YNTS
Here block is the pointer to the start of a piece of memory space previously allocated.

,

Other books

Sacred by Dennis Lehane
Theirs to Claim by Newton, LaTeisha
The Cat Next Door by Marian Babson
Rise (Roam Series, Book Three) by Stedronsky, Kimberly
No Nest for the Wicket by Andrews, Donna
Bachelor Unleashed by Brenda Jackson
Adrift in the Noösphere by Damien Broderick
The Heaven Trilogy by Ted Dekker