Understanding and Using C Pointers

Errata for Understanding and Using C Pointers

Submit your own errata for this product.


The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".

The following errata were submitted by our customers and approved as valid errors by the author or editor.

Color Key: Serious Technical Mistake Minor Technical Mistake Language or formatting error Typo Question Note Update



Version Location Description Submitted By Date Submitted Date Corrected
Safari Books Online
1
chapter 1, "pointers and memory" section, right before "declaring pointers" subsection

uh, the safari version of this book doesn't have pages (so, sorry, no page number or succinct location). in the *undefined* section it says "A list of *unspecified* behavior can be found at CERT Secure Coding Appendix CC." (emphasis mine) it should say, "A list of *undefined* behavior can be found at CERT Secure Coding Appendix CC" (as the CERT Secure Coding Appendix CC is entitled "Undefined Behavior" and "unspecified behavior" was covered in the previous paragraph).

Note from the Author or Editor:
In Chapter 1, Introduction, towards the end of the section titled, "Why You Should Become Proficient with Pointers", the third bullet contains the following sentence: "A list of unspecified behavior can be found at CERT Secure Coding Appendix CC." It should read: "A list of undefined behavior can be found at CERT Secure Coding Appendix CC."

unlisted  May 16, 2013  Apr 04, 2014
Safari Books Online
1
Ch 1 -> "Common Uses of Pointers" -> "Constants and Pointers" -> "Pointers to a Constant"

In discussing pointers to constants (meaning pointers that point to values that cannot be changed [at least by way of the pointer]), it is said: "The pointer thinks it is pointing to a constant integer; therefore, it does allow the modification of the integer using the pointer." It should say: "The pointer thinks it is pointing to a constant integer; therefore, it does *not* allow the modification of the integer using the pointer." (Emphasis mine.) Just a small typo.

Note from the Author or Editor:
Change: "The pointer thinks it is pointing to a constant integer; therefore, it does allow the modification of the integer using the pointer." To read: "The pointer thinks it is pointing to a constant integer; therefore, it does not allow the modification of the integer using the pointer."

unlisted  May 18, 2013  Apr 04, 2014
PDF
Page 4
2nd paragraph

The text says "However, in the new C standard, C11, variable size arrays are supported.". While technically speaking this sentence is true, it suggest that variable size arrays are only supported by C11, not earlier language standards. Truth is, this feature was added in much earlier, C99 standard.

Note from the Author or Editor:
Page 4 - Replace the following sentence; "However, in the new C standard, C11, variable size arrays are supported." With: "However, variable size arrays have been supported since C99.".

Krzysztof Adamski  Apr 05, 2014 
Printed
Page 14
second bullet of paragraph 'Pointer to void'

A pointer to void will never be equal to another pointer. ? should be ? : A pointer to void will never be equal to another pointer to void. reasoning : a pointer to void can be assigned the value of a non-void pointer

Note from the Author or Editor:
On page 14, second bullet, add the following sentence: The actual behavior of void pointers is system dependent.

Andre  Aug 02, 2013  Apr 04, 2014
Printed
Page 17
5th line

intptr_t and uintprt_t should be intptr_t and uintptr_t

Note from the Author or Editor:
On page 17, fifth line, change "uintprt_t" to "uintptr_t".

Anonymous  Jul 05, 2013  Apr 04, 2014
PDF
Page 23
middle of the page (a warning example)

The correct option to display that kind of warning message is -Wpointer-arith, not -Wpointerarith, if the compiler is GCC.

Note from the Author or Editor:
On page 23 add a hyphen to: ... [-Wpointerarith] So it appears as: ... [-Wpointer-arith]

Anonymous  Oct 02, 2013  Apr 04, 2014
PDF
Page 23
Section "Pointers to void and addition"

>Here we will assume the size of a pointer to void is four. >the resulting address contained in pv will be incremented by four bytes. Pointer arithmetic will be calcurated based on the size of base type, not pointer type. In this case pv + 1 != pv + sizeof(void *) pv + 1 == pv + sizeof(void) On the ordinary environment address of pv+1 will be 1 larger than pv.

Note from the Author or Editor:
On page 23, replace the sentence: However, the resulting address contained in pv will be incremented by four bytes. To: However, the resulting address contained in pv will be incremented by one byte. Most compilers will treat the data type void as if it has a size of one byte. Since the pointer points to void, the address is incremented by one. Most compilers will issue a warning if the sizeof operator is used with the void data type. This is different from the size of a pointer to void which is normally four bytes.

Anonymous  Oct 02, 2013  Apr 04, 2014
Printed
Page 24
diagram

addr 116 should be labeled p1, addr 120 should be labeled p2

Note from the Author or Editor:
On page 24 change the text in Figure 1-9 from: p0 116 p0 120 to: p1 116 p2 120

AdamZ  Jun 03, 2013  Apr 04, 2014
Printed
Page 26
Figure 1-10

The array called "title" in Figure 1-10 should be named "titles".

Richard Reese
Richard Reese
O'Reilly AuthorO'Reilly Blogger 
Mar 11, 2014  Apr 04, 2014
PDF
Page 46
2nd paragraph from the beginning of the section "The alloca function..."

The paragraph reads: ...In the following example, an array of char is allocated for use in a function: void compute(int size) { char* buffer[size]; ... } Either the description or the code is wrong. The code defines and allocates an array of pointers to char. The description "an array of chars is allocated" should be coded as: char buffer[size];

Note from the Author or Editor:
On page 46 change the following line of code: char* buffer[size]; to: char buffer[size];

Miguel A. Rodriguez-Jodar  May 23, 2013  Apr 04, 2014
PDF, Mobi
Page 61
Last paragraph

"Passing a pointer to the object means the object does *not*.... " (Last sentence) The page number is from the PDF format of the book.

Note from the Author or Editor:
Change: "Passing a pointer to the object means the object does have to be copied, and we can access the object through the pointer." To: "Passing a pointer to the object means the object does not have to be copied, and we can access the object through the pointer."

Amit Saha  May 11, 2013  Apr 04, 2014
Printed
Page 64

sentence should say “We cannot pass the address of an integer constant to a pointer to an integer, as this would allow a constant value to be modified."

Note from the Author or Editor:
On page 64 change: “We cannot pass the address of an integer constant to a pointer to a constant, as this would allow a constant value to be modified." To: "We cannot pass the address of an integer constant to a pointer to an integer, as this would allow a constant value to be modified."

AdamZ  Jun 03, 2013  Apr 04, 2014
Printed
Page 69
example at bottom of the page

the call of allocateArray should be : allocateArray(vector,5,45) and not allocateArray(&vector,5,45) because &vector is not a simple pointer but a pointer to a pointer As a result,iIn Figure 3-8 , the value of the parameter 'arr' in the stack frame in the 'Before malloc' section should be NULL

Note from the Author or Editor:
When we try to execute the example, it will normally fail as we are trying to use vector as an array but its address is NULL. This will result in a segmentation fault type error. In addition, it will generate an warning complaining about incompatible pointer types.

Andre  Aug 05, 2013  Apr 04, 2014
PDF
Page 74
7 lines below Passing Function Pointers

Change int subtract(int num1, int num2) to int sub(int num1, int num2)

Note from the Author or Editor:
On page 74, in the bottom code sequence, change int subtract(int num1, int num2) to int sub(int num1, int num2)

James  Jul 12, 2013  Apr 04, 2014
Printed
Page 75-76
Several places

When the "subtract" function was renamed on page 74, several references to the function were not updated. The word "subtract" needs to be replaced with "sub" in the following locations: Page 75: Second paragraph of the section: Returning Function Pointer "It will return a pointer to either the add or the subtract function" First code sequence in that section: " case: '-': retrun subtract;" Page 76: Third paragraph, last sentence: "We will use this definition in conjunction with the add and subtract functions ..." Fourth paragraph: "... we will then assign the add and subtract functions ..." Third code sequence: " operations['-'] = subtract;"

Richard Reese
Richard Reese
O'Reilly AuthorO'Reilly Blogger 
Apr 16, 2014 
Printed
Page 76
first paragraph

....If the number of values is less than the size of the array, as in this example, the value is used to initialize every element of the array. This doesn't appear quite correct to me ; In my opinion the rule is that all array elements that do not have a corresponding initializer value , are initialized to 0 (or NULL in case of a pointer). In the given example : operation operations[128] = {NULL} , the result of both interpretations is identical because a NULL value is used as the first initializer

Note from the Author or Editor:
On page 76, first paragraph, change the sentence reading: If the number of values is less than the size of the array, as in this example, the value is used to initialize every element of the array. To: If the number of values is less than the size of the array, as in this example, then the remaining elements of the array are initialized to 0.

Andre  Aug 05, 2013  Apr 04, 2014
Printed
Page 85
4th paragraph

"The notation vector+i generates machine code that starts at location vector, adds i to the address, and then uses the contents at this address." "vector+i" should be replaced with *(vector+i) since later the sentence says, "contents at this address".

Note from the Author or Editor:
On page 85 in the second paragraph of the section titled, Differences Between Arrays and Pointers, change both occurrences of: vector+i To: *(vector+i)

Joe Flowers  Jun 07, 2013  Apr 04, 2014
PDF
Page 86
The last paragraph (warning section)

we used *(pv+i) instead of *pv+1. should be we used *(pv+i) instead of *pv+i.

Note from the Author or Editor:
On page 86 at the bottom of the page cchange: we used *(pv+i) instead of *pv+1. TO: we used *(pv+i) instead of *pv+i. The difference is the use of the letter i instead of the number 1.

Anonymous  Jul 22, 2013  Apr 04, 2014
PDF
Page 89
The last paragraph

"cat." should be " cat"

Note from the Author or Editor:
On page 89, last paragraph, change: "cat.' To: " cat". Blanks have been inserted in the string to reflect its original condition.

Anonymous  Jul 22, 2013  Apr 04, 2014
Printed
Page 89
First para after code sample

"The first while loop uses the tmp variable" There is no tmp variable. The first while loop uses a temporary variable called "old".

Note from the Author or Editor:
On page 89, first paragraph after the code, first sentence, change the variable "tmp" to "old".

Leam Hall  Jul 26, 2013  Apr 04, 2014
Printed
Page 89
Last sentence of last paragraph

"The memory in red is the old..." In the printed book there is no color. Perhaps "The memory the shaded area is the old..."

Note from the Author or Editor:
On page 89, last paragraph, last sentence, change: The memory in red is the old ... Should read: The shaded memory is the old ...

Leam Hall  Jul 26, 2013  Apr 04, 2014
Printed
Page 114
diagram

globalHeader is displayHeader

Note from the Author or Editor:
In Figure 5-5 on page 114 change the stack frame titled "globalHeader" located above "main" with "displayHeader".

AdamZ  Jun 03, 2013  Apr 04, 2014
Printed
Page 120

strcat mentioned 2 times should read strcpy

Note from the Author or Editor:
On page 120 replace the following text found at the end of the page: "Always allocate dedicated memory for the concatentation: strcat(error, errorMessage);" with: "Always allocate dedicated memory for the concatentation."

AdamZ  Jun 03, 2013  Apr 04, 2014
Printed
Page 121
last paragraph

...We used parentheses to force the post increment operator to execute first , incrementing the pointer..... Remark : this isn't necessary because the postfix-operator ++ has a higher precedence than the unary indirection operator *

Note from the Author or Editor:
On page 122, first sentence, change: Otherwise, the character referenced by string would have been incremented, which is not what is desired: To: While the use of parentheses is not required, since the post-increment operator has higher precedence than the dereference operator, it makes the intent clear.

Andre  Aug 07, 2013  Apr 04, 2014
PDF
Page 121
code fragment on the middle of the page.

In the code example char* path = "C:"; char* currentPath = (char*) malloc(strlen(path)+2); currentPath = strcat(currentPath,"\\"); memory for "currentPath" is allocated, not initialized. currentPath does not have anything even NUL terminator. The result of strcat is unexpected. This example needs copying path string to the currentPath before invoking strcat, as follows. char* path = "C:"; char* currentPath = (char*) malloc(strlen(path)+2); strcpy(currentPath, path); currentPath = strcat(currentPath,"\\");

Note from the Author or Editor:
On page 121, change the first code sequence to: char path[] = "C:"; char* currentPath = (char*) malloc(strlen(path) + 2); strcpy(currentPath,path); strcat(currentPath, "\\"); This copies "C:" to currentPath first and then performs concatenation.

Anonymous  Aug 22, 2013  Apr 04, 2014
Printed
Page 122
a paragraph before Figure 5-12

> In the second statement, the > address-of operator is used explicitly. This is redundant and > unnecessary. In addition, it will often generate a warning. The type of &simpleArray is not "char *" but "char **", because address-of operator is applied to char* variable. Result of passing &simpleArray to stringLength is not "redundant". It will end with imcompatible pointer warning.

Note from the Author or Editor:
Page 122, replace the sentences: This is redundant and unnecessary. In additional, it will often generate a warning. With: While this will work, we are passing a pointer to a pointer to a char instead of a pointer to a char which will generate a warning .

Anonymous  Oct 05, 2013  Apr 04, 2014
Printed
Page 131
first paragraph (after the code fragment)

typedef int (ftprOperation)(const char*,const char*) ?? should be ?? typedef int (* ftprOperation)(const char*,const char*)

Note from the Author or Editor:
On page 131, code fragment after first paragraph, change: typedef int (ftprOperation)(const char*,const char*) To: typedef int (*ftprOperation)(const char*,const char*)

Andre  Aug 07, 2013  Apr 04, 2014
Printed
Page 136
last paragraph

When we declare a variable of this type or dynamically allocate memory for this type, the three pointers will contain garbage. refinement : when a declared variable of a structure type has static storage duration (i.e. is declared outside all functions (global variable) or is declared as static within a function), then the structure members are initialized to 0 (NULL for pointers)

Note from the Author or Editor:
On page 136, last paragraph, after the sentence: When we declare a variable of this type or dynamically allocate memory for this type, the three pointers will contain garbage. Add: However, when a declared variable of a structure type has static storage duration (i.e. is declared outside all functions (global variable) or is declared as static within a function), then the structure members are initialized to 0 (NULL for pointers).

Andre  Aug 08, 2013  Apr 04, 2014
Printed
Page 139
diagram

person is ptrPerson

Note from the Author or Editor:
Change the variable "person" in Figure 6-4 on page 139 to "ptrPerson".

AdamZ  Jun 03, 2013  Apr 04, 2014
Printed
Page 142
4th paragraph

The fourth paragraph says; The DISPLAY function pointer designates a function that is passed void (should say void *) and returns void.

Note from the Author or Editor:
Page 142, fourth paragraph. The sentence that reads: The DISPLAY function pointer designates a function that is passed void and returns void. It should read: The DISPLAY function pointer designates a function that is passed a pointer to void and returns void.

Toni Granholm  Jul 30, 2013  Apr 04, 2014
Printed
Page 146
Figure 6-6

In the figure, linkedList variable has address of memory block allocated in the heap. linkedList is not a pointer. It is declared as a local LinkedList structure in the code fragment in the page 145. linkedList is need to be drawn as structure allocated in the stack frame of main function.

Note from the Author or Editor:
That is correct. The easiest thing to do is to move the contents at address 700 (head, tail, and current pointers) to inside of the linkedList varible in the main stack frame. This replaces the number 700 currently inside of the linkedList variable. Otherwise the figure does not change.

Anonymous  Nov 20, 2013  Apr 04, 2014
Printed
Page 154
Second to the last paragraph

Change the sentence: "A common ordering is to add a new node to a tree such that all of the node’s children possess a value less than the parent node and all of the children on the right posses a value greater than the parent node." To: "A common ordering is to add a new node to a tree such that all of the node’s children on the left possess a value less than the parent node and all of the children on the right posses a value greater than the parent node." "on the left" is added.

Richard Reese
Richard Reese
O'Reilly AuthorO'Reilly Blogger 
Mar 11, 2014  Apr 04, 2014
Printed
Page 155
insertNode code sample

The code, as it stands, will corrupt the root node pointer. Adding samuel, sally and susan works fine. Adding sally, samuel and susan does not. The code sample says if((*root)->left != NULL) { *root = (*root)->left; } else { ... .... if((*root)->right != NULL) { *root = (*root)->right; } else { It should say if((*root)->left != NULL) { root = &(*root)->left; } else { ... .... if((*root)->right != NULL) { root = &(*root)->right; } else {

Note from the Author or Editor:
On page 155 replace the insertNode function with the following: void insertNode(TreeNode **realRoot, COMPARE compare, void* data) { TreeNode *node = (TreeNode*) malloc(sizeof (TreeNode)); node->data = data; node->left = NULL; node->right = NULL; TreeNode *root = *realRoot; if (root == NULL) { *realRoot = node; return; } while (1) { if (compare((root)->data, data) > 0) { if ((root)->left != NULL) { root = (root)->left; } else { (root)->left = node; break; } } else { if ((root)->right != NULL) { root = (root)->right; } else { (root)->right = node; break; } } } } The previous version used the root variable when traversing the tree.Since the root variable and the "real root" of the tree passed to this function are the same, as the tree was traversed, the real root was also modified. The only time it should be modified is if the tree is empty. The new version corrects this problem by adding a realRoot variable that is only modified if the tree is empty.

Toni Granholm  Aug 02, 2013  Apr 04, 2014
Printed
Page 168
6th paragraph

srtlcat should be strlcat

Note from the Author or Editor:
On page 168, sixth paragraph, change "srtlcat" to "strlcat".

Anonymous  Jul 03, 2013  Apr 04, 2014
Printed
Page 188

in the pthread_create function (void *) repeated twice ; should only show this once

Note from the Author or Editor:
On page 188 replace the following line: dotProduct, (void *) (void*) (product)); with: dotProduct, (void*) (product));

AdamZ  Jun 03, 2013  Apr 04, 2014
Printed
Page 191-193
code examples

comment on the code on page 191-192 and on the suggested corrections in the 'confirmed errata' list On my system (Linux, gcc), the suggested corrections in the errata list, cause the following compiler warnings : - for function 'addNode : linkmain.c:22:2: warning: passing argument 2 of ‘addNode’ from incompatible pointer type [enabled by default] link.h:5:6: note: expected ‘void **’ but argument is of type ‘struct Person *’ - for function 'removeNode' : linkmain.c:29:9: warning: assignment from incompatible pointer type [enabled by default] In my opinion the corrections that are needed are : - in the definition of struct _node : the declaration 'Data* data' should be 'Data data' - in the function 'removeNode' : the declaration 'Data* data' should be 'Data data' Indeed, the type 'Data' is a 'pointer to void' , so 'Data *' is a 'pointer to pointer to void' and that is not what we need here. Nevertheless, on my system (Linux, gcc) ,the code in the book compiles without warnings and executes correctly. I did some tests and found that the reason is because one can assign the value of a 'pointer to void' to a 'pointer to a pointer to void' and even to a 'pointer to a pointer to a pointer to void' without any warning or execution problem. This is what happens in 'addNode' in the statement 'node->data = data;' where 'node->data' is of type 'Data *' (= void **) . When 'addNode' is called with a pointer to Person as second argument, the pointer to Person is implicitly converted to a pointer to void ,according to the type of the second formal parameter of addNode , which is of type 'Data' (= void *). The statement 'node->data = data;' then assigns the value to node->data (type void **). In the function 'removeNode' , the type of 'data' in the return statement is of type 'Data *' ( = void **). However this type is implicitly converted to type 'Data' (= void *), according to the return type in the function header of removeNode. Thus, in the main program, the result of the statement 'person = removeNode(list);' is that 'person' is implicitly converted to type 'void *' , which is again implicitly converted to type 'Person *' in the call of 'displayPerson' .This makes the program compile and execute correctly.

Note from the Author or Editor:
On page 192 the addNode method's first line should appear as: void addNode(LinkedList* list, Data data) { On page 193 the removeNode method's first line should appear as: Data removeNode(LinkedList* list) { The previous errata incorrectly changed the code.

Andre  Aug 17, 2013  Apr 04, 2014