K&R2 Secition 5.9 - major blunders

T

TTroy

I FOUND MAJOR ERRORS in K&R2 (making it almost useless for the herein
mentioned topics).

K&R2 Section 5.9 Pointers vs. Multidimension Arrays starts of like
this...

"Newcomers to C are somtimes confused about the difference between a
two-dimensional array and an array of pointers..."

then continues to explain int *b[10]; to be...

"For b, however, the definition only allocates 10 pointers ... Assuming
that each element of b does point to a twenty element array,then there
will be 200 ints set aside, plus ten cells for pointers... "

Is it just me, or is that explanation only valid for int (*b)[10];
????

I'm pretty sure K&R2 is totally wrong in this section (had me confused
for a while).

Later on in section 5.9, it says "... by far the most frequent use of
arrays of pointers is to store character strings of diverse lengths..."

Once again, this seems totally wrong.
char *strings[] = {"Bob","Dave","Jack");
'strings' is only managing pointers to anonymous objects that are
automatically created by the initialization (which there is no mention
of in this section). 'strings' doesn't strore "Bob" "Dave" "Jack".

All in all, K&R2 has been an amazing book, but this one section (which
is often the hardest for beginners) makes it a less amazing book
(rather average).

Am I right here, or am I wrong (I'm pretty sure I'm right, but I still
don't know how these mistakes could be in the book, considering the
authors and the many decades it has been the bible).

How come these errors weren't caught? How come none of the errata I
have found mentions these? Am I totally wrong?
 
M

Martin Ambuhl

TTroy said:
I FOUND MAJOR ERRORS in K&R2 (making it almost useless for the herein
mentioned topics).

K&R2 Section 5.9 Pointers vs. Multidimension Arrays starts of like
this...

"Newcomers to C are somtimes confused about the difference between a
two-dimensional array and an array of pointers..."

then continues to explain int *b[10]; to be...

"For b, however, the definition only allocates 10 pointers ... Assuming
that each element of b does point to a twenty element array,then there
will be 200 ints set aside, plus ten cells for pointers... "

Is it just me, or is that explanation only valid for int (*b)[10];
????

It's just you; and you are dead wrong.
int *b[10];
is the declaration for an array[10] of pointers to int.
int (*b)[10];
is the declaration for *one* pointer to an array[10] of int.
I'm pretty sure K&R2 is totally wrong in this section (had me confused
for a while).

You dead wrong. This is frequently the case for people who are "pretty
sure" that a text that has been gone over carefully for some 30 years is
wrong.
Later on in section 5.9, it says "... by far the most frequent use of
arrays of pointers is to store character strings of diverse lengths..."

Once again, this seems totally wrong.
char *strings[] = {"Bob","Dave","Jack");
'strings' is only managing pointers to anonymous objects that are
automatically created by the initialization (which there is no mention
of in this section). 'strings' doesn't strore "Bob" "Dave" "Jack".

The use of the array of pointers is to store the strings. 'strings'
doesn't do anything, so that it doesn't store is beside the point as
much as that it doesn't do integrals. It's an array.
 
T

TTroy

TTroy said:
I FOUND MAJOR ERRORS in K&R2 (making it almost useless for the herein
mentioned topics).

K&R2 Section 5.9 Pointers vs. Multidimension Arrays starts of like
this...

"Newcomers to C are somtimes confused about the difference between a
two-dimensional array and an array of pointers..."

then continues to explain int *b[10]; to be...

"For b, however, the definition only allocates 10 pointers ... Assuming
that each element of b does point to a twenty element array,then there
will be 200 ints set aside, plus ten cells for pointers... "

Is it just me, or is that explanation only valid for int (*b)[10];
b above should be: int (*b[10])[20];
 
T

TTroy

Martin said:
TTroy said:
I FOUND MAJOR ERRORS in K&R2 (making it almost useless for the herein
mentioned topics).

K&R2 Section 5.9 Pointers vs. Multidimension Arrays starts of like
this...

"Newcomers to C are somtimes confused about the difference between a
two-dimensional array and an array of pointers..."

then continues to explain int *b[10]; to be...

"For b, however, the definition only allocates 10 pointers ... Assuming
that each element of b does point to a twenty element array,then there
will be 200 ints set aside, plus ten cells for pointers... "

Is it just me, or is that explanation only valid for int (*b)[10];
????

It's just you; and you are dead wrong.
int *b[10];

Each element of b doesn't point to a 20 element array of int. Each
element of b points to an int. The authors should have said "Assuming
that each element of b does point to an int which happens to be the
first element of a 20 int array." This mistake is crucial because
there really exists something totally different that fits their "not
very accurate" description. This leads to confusion. If I point at a
pencil and tell you that it's an instrument to write with and it has
ink in it which is permanent, then that's a big mistake for two
reasons: I'm 'slightly' off on my explanation of the pencil, and most
importantly, my explanation is really the qualities of something else:
a pen.
is the declaration for an array[10] of pointers to int.
int (*b)[10];
is the declaration for *one* pointer to an array[10] of int.

Yeah, I meant int (*b[10])[20]; This exactly fits the description.
You dead wrong.

I gave an explanation as to why I thought K&R2 was wrong, but you gave
no explanation to explain why I am 'dead wrong.' All you did was
explain what thoise two definitions above were, without relating it to
anything.
This is frequently the case for people who are "pretty
sure" that a text that has been gone over carefully for some 30 years is
wrong.

I'm pretty sure it's wrong (the explanation is "close" to the truth,
but since it's accurately describing something totally different,
that's what makes it very wrong).
Later on in section 5.9, it says "... by far the most frequent use of
arrays of pointers is to store character strings of diverse lengths..."

Once again, this seems totally wrong.
char *strings[] = {"Bob","Dave","Jack");
'strings' is only managing pointers to anonymous objects that are
automatically created by the initialization (which there is no mention
of in this section). 'strings' doesn't strore "Bob" "Dave" "Jack".

The use of the array of pointers is to store the strings.

No it's not, and thinking like this is dangerous. Say you have a
structure that you want to have strings in it, if you chose to have a
(char *) array in it, and you *think* it's holding the strings, you'll
be in big trouble if you try to write the structure to a file. Arrays
of pointers to char that point to anonymous string objects are just
'managing' references to the strings (by pointing to their first
characters).
'strings'
doesn't do anything, so that it doesn't store is beside the point as
much as that it doesn't do integrals. It's an array.

Besides the point? If it isn't for the diagram that following their
explanation, this would been a very dangerous mistake. Also there is
no mention of how the strings are created or where they are actually
stored, which compounds the mistake. And also again, the
initialization with definition makes it look like the strings are
actually being stored in the array too.

ex:

"... by far the most frequent use of
arrays of pointers is to store character strings of diverse lengths..."

followed by:

char *strings[]= {"string1", "string2", "string3");

This might confuse very many newbie readers (it didn't confuse me, but
the mistake I mentioned above did). It *looks* like the strings are
being stored in the array, and the literature above it implies storage.
Plus the [] array notion also implies storage. Also the lack of
explanation of how/where these strings are stored also implies they are
stored in the strings array.



All I'm requesting is all the people who maintain errata lists for this
book take this into account.
 
T

TTroy

Martin said:
TTroy said:
I FOUND MAJOR ERRORS in K&R2 (making it almost useless for the herein
mentioned topics).

K&R2 Section 5.9 Pointers vs. Multidimension Arrays starts of like
this...

"Newcomers to C are somtimes confused about the difference between a
two-dimensional array and an array of pointers..."

then continues to explain int *b[10]; to be...

"For b, however, the definition only allocates 10 pointers ... Assuming
that each element of b does point to a twenty element array,then there
will be 200 ints set aside, plus ten cells for pointers... "

Is it just me, or is that explanation only valid for int (*b)[10];
????

It's just you; and you are dead wrong.
int *b[10];

Each element of b doesn't point to a 20 element array of int. Each
element of b points to an int. The authors should have said "Assuming
that each element of b does point to an int which happens to be the
first element of a 20 int array." This mistake is crucial because
there really exists something totally different that fits their "not
very accurate" description. This leads to confusion. If I point at a
pencil and tell you that it's an instrument to write with and it has
ink in it which is permanent, then that's a big mistake for two
reasons: I'm 'slightly' off on my explanation of the pencil, and most
importantly, my explanation is really the qualities of something else:
a pen.
is the declaration for an array[10] of pointers to int.
int (*b)[10];
is the declaration for *one* pointer to an array[10] of int.

Yeah, I meant int (*b[10])[20]; This exactly fits the description.
You dead wrong.

I gave an explanation as to why I thought K&R2 was wrong, but you gave
no explanation to explain why I am 'dead wrong.' All you did was
explain what thoise two definitions above were, without relating it to
anything.
This is frequently the case for people who are "pretty
sure" that a text that has been gone over carefully for some 30 years is
wrong.

I'm pretty sure it's wrong (the explanation is "close" to the truth,
but since it's accurately describing something totally different,
that's what makes it very wrong).
Later on in section 5.9, it says "... by far the most frequent use of
arrays of pointers is to store character strings of diverse lengths..."

Once again, this seems totally wrong.
char *strings[] = {"Bob","Dave","Jack");
'strings' is only managing pointers to anonymous objects that are
automatically created by the initialization (which there is no mention
of in this section). 'strings' doesn't strore "Bob" "Dave" "Jack".

The use of the array of pointers is to store the strings.

No it's not, and thinking like this is dangerous. Say you have a
structure that you want to have strings in it, if you chose to have a
(char *) array in it, and you *think* it's holding the strings, you'll
be in big trouble if you try to write the structure to a file. Arrays
of pointers to char that point to anonymous string objects are just
'managing' references to the strings (by pointing to their first
characters).
'strings'
doesn't do anything, so that it doesn't store is beside the point as
much as that it doesn't do integrals. It's an array.

Besides the point? If it isn't for the diagram that following their
explanation, this would been a very dangerous mistake. Also there is
no mention of how the strings are created or where they are actually
stored, which compounds the mistake. And also again, the
initialization with definition makes it look like the strings are
actually being stored in the array too.

ex:

"... by far the most frequent use of
arrays of pointers is to store character strings of diverse lengths..."

followed by:

char *strings[]= {"string1", "string2", "string3");

This might confuse very many newbie readers (it didn't confuse me, but
the mistake I mentioned above did). It *looks* like the strings are
being stored in the array, and the literature above it implies storage.
Plus the [] array notion also implies storage. Also the lack of
explanation of how/where these strings are stored also implies they are
stored in the strings array.



All I'm requesting is all the people who maintain errata lists for this
book take this into account.
 
K

Keith Thompson

TTroy said:
I FOUND MAJOR ERRORS in K&R2 (making it almost useless for the herein
mentioned topics).

K&R2 Section 5.9 Pointers vs. Multidimension Arrays starts of like
this...

"Newcomers to C are somtimes confused about the difference between a
two-dimensional array and an array of pointers..."

then continues to explain int *b[10]; to be...

"For b, however, the definition only allocates 10 pointers ... Assuming
that each element of b does point to a twenty element array,then there
will be 200 ints set aside, plus ten cells for pointers... "

Is it just me, or is that explanation only valid for int (*b)[10];
????

I'm pretty sure K&R2 is totally wrong in this section (had me confused
for a while).

I don't have my K&R2 handy, but the portion you quoted seems correct.

int *b[10] declares an array of 10 pointers (each of which is a
pointer-to-int). When K&R say the definition "only allocates 10
pointers", they mean it allocates space for the pointer objects
themselves, not for what they point to. Space for the 200 ints (10
arrays of 20 elements each) has to be allocated separately.

int (*b)[10] would declare a single pointer, pointing to an array of
10 ints.
Later on in section 5.9, it says "... by far the most frequent use of
arrays of pointers is to store character strings of diverse lengths..."

Once again, this seems totally wrong.
char *strings[] = {"Bob","Dave","Jack");
'strings' is only managing pointers to anonymous objects that are
automatically created by the initialization (which there is no mention
of in this section). 'strings' doesn't strore "Bob" "Dave" "Jack".

Strictly speaking, the pointers don't store character strings; they
point to character strings. It might have been a bit more precise to
say that arrays of pointers are used to *manage* character strings if
diverse lengths.
 
M

Martin Ambuhl

TTroy said:
Each element of b doesn't point to a 20 element array of int. Each
element of b points to an int.


/*
* You clearly have a conceptual problem. Let's try to address it. The
* text says that we should *assume* that each element of b points to an
* array of 20 ints, not that the declaration makes it so. How might
* this happen?
*/
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int *b[10];
size_t i, j;

for (i = 0; i < 10; i++)
if (!(b = malloc(20 * sizeof *b))) {
fprintf(stderr, "problem allocating b[%u]\n", (unsigned) i);
for (j = 0; j < i; j++)
free(b);
}
/* Each element of b now points to a region of memory whose contents
is an array[20] of int. Indeed, each element of b points to an
array[20] of int */

for (i = 0; i < 10; i++)
for (j = 0; j < 20; j++)
b[j] = 100 * i + j;
for (j = 0; j < 20; j++)
for (i = 0; i < 10; i++)
printf("%3d%c", b[j], (i == 9) ? '\n' : ' ');

for (i = 0; i < 10; i++)
free(b);
return 0;
}

[output]
0 100 200 300 400 500 600 700 800 900
1 101 201 301 401 501 601 701 801 901
2 102 202 302 402 502 602 702 802 902
3 103 203 303 403 503 603 703 803 903
4 104 204 304 404 504 604 704 804 904
5 105 205 305 405 505 605 705 805 905
6 106 206 306 406 506 606 706 806 906
7 107 207 307 407 507 607 707 807 907
8 108 208 308 408 508 608 708 808 908
9 109 209 309 409 509 609 709 809 909
10 110 210 310 410 510 610 710 810 910
11 111 211 311 411 511 611 711 811 911
12 112 212 312 412 512 612 712 812 912
13 113 213 313 413 513 613 713 813 913
14 114 214 314 414 514 614 714 814 914
15 115 215 315 415 515 615 715 815 915
16 116 216 316 416 516 616 716 816 916
17 117 217 317 417 517 617 717 817 917
18 118 218 318 418 518 618 718 818 918
19 119 219 319 419 519 619 719 819 919


The authors should have said "Assuming
that each element of b does point to an int which happens to be the
first element of a 20 int array."

You are addressing pedants; don't try to outdo us at our own game. You
just look silly.
This mistake is crucial because
there really exists something totally different that fits their "not
very accurate" description.

It is not a mistake.
This leads to confusion.

Yes, I admit you are confused.
If I point at a
pencil and tell you that it's an instrument to write with and it has
ink in it which is permanent, then that's a big mistake for two
reasons: I'm 'slightly' off on my explanation of the pencil, and most
importantly, my explanation is really the qualities of something else:
a pen.

You may now return to your class in Foucault where this silliness is
rewarded.
 
I

infobahn

TTroy said:
I FOUND MAJOR ERRORS in K&R2 (making it almost useless for the herein
mentioned topics).

No, you didn't.
K&R2 Section 5.9 Pointers vs. Multidimension Arrays starts of like
this...

"Newcomers to C are somtimes confused about the difference between a
two-dimensional array and an array of pointers..."
Indeed.


then continues to explain int *b[10]; to be...

"For b, however, the definition only allocates 10 pointers ...
Correct.

Assuming
that each element of b does point to a twenty element array,then there
will be 200 ints set aside, plus ten cells for pointers... "

Yes. So if you do something like this:

for(i = 0; i < 10; i++)
{
b = malloc(20 * sizeof *b);
if(b == NULL) abort(); /* ! */
}

puts("At this point, 200 ints are set aside,"
" plus the size of the b array - i.e. 10 pointers");
Is it just me, or is that explanation only valid for int (*b)[10];
????

It's just you.
I'm pretty sure K&R2 is totally wrong in this section (had me confused
for a while).

Their explanation looks clear enough to me. And correct, too.
Later on in section 5.9, it says "... by far the most frequent use of
arrays of pointers is to store character strings of diverse lengths..."

Once again, this seems totally wrong.

Here, you have half a point; "to store pointers to" would have been
more precise.

Am I totally wrong?

Mostly wrong, yes.
 
K

Kiru Sengal

TTroy said:
I FOUND MAJOR ERRORS in K&R2 (making it almost useless for the herein
mentioned topics).

K&R2 Section 5.9 Pointers vs. Multidimension Arrays starts of like
this...

"Newcomers to C are somtimes confused about the difference between a
two-dimensional array and an array of pointers..."

Probably.


then continues to explain int *b[10]; to be...

"For b, however, the definition only allocates 10 pointers ... Assuming
that each element of b does point to a twenty element array,then there
will be 200 ints set aside, plus ten cells for pointers... "

Would changing 'point to a' to 'point into a' twenty element array be
better for you? If so you are free to do so in your copy of the book.
Is it just me, or is that explanation only valid for int (*b[10])[20];
????

Well, it does and it doesn't. It fits the part of the explanation that
says "Assuming each element of b does point to a twenty element array"
as you have quoted, but it doesn't fit the part that comes after what
you have quoted that explains how each array/row can be of different
lengths. The whole section read in its entirety does lead one to
realize that 'to' really means 'into.' The reader should be able to
figure that out.
I'm pretty sure K&R2 is totally wrong in this section (had me confused
for a while).

Later on in section 5.9, it says "... by far the most frequent use of
arrays of pointers is to store character strings of diverse lengths..."

Take a pen, and change 'store' to 'manage.' K&R didn't get too
detailed here probably because the reader would already know what's
going from reading the well explained in previous sections on the issue
(5.5, 5.6). The diagram at the end of 5.9 also serves as an good
comparison between what was really happening (arrays of pointers to
strings stored elsewhere) and what it might be confused with (arrays of
strings held internally - 2 dimensional char array).

Incidentally, section 5.10 also explains *argv[] as "a pointer to an
array of character strings" and says "argv[0] is the name by which the
program was invoked." So go ahead and change those to "a pointer to a
pointer to a string(this probably would confuse beginners)" and
"argv[0] points to the program name."

The changes aren't really needed, since the diagram clearly shows what
is meant, and a beginner might not be able to get passed the section if
it was 110% accurate. Learning is cumulative, and it's sometimes better
to refrain from being too pedantic early on in someone's education of a
subject, because being so might mentally "hold them back" from learning
further. In your early years of learning chemistry, you were probably
taught basic notions of K, L, M, N shells, but in your later years you
probably thought "they were totally wrong a few years ago!!." No they
weren't, they refrained from being 100% detailed/accurate to help you
move on and learn other aspects of the earlier course (which were also
probably 'less than 100% accurate/detailed').

Once again, this seems totally wrong.
char *strings[] = {"Bob","Dave","Jack");
'strings' is only managing pointers to anonymous objects that are
automatically created by the initialization (which there is no mention
of in this section). 'strings' doesn't strore "Bob" "Dave" "Jack".

See now, you are making the same type of statement K&R were making
about the pointers to int arrays. See where you said "'strings' is only
managing pointers 'to' anonymous objects' instead of "'strings' is only
managing pointers 'to the first element..'" So from context it's easy
to tell what is meant by 'pointing to' an object or array.
Technically, pointing to an object/array means the pointer has a
reference type with size equal to the whole objects, but there is no
harm with using 'pointing to' to describe 'pointing into the first
element of' because context clears up the confusion.

Probably the most unambiguous use of 'pointing to' to refer to
'pointing into first element of' is with the word "strings." Almost
nobody says things like (char *b = "bill";) b is a pointer to the
'first element of a string.' Almost everyone says b is a pointer to a
string. This is similar to the 'to an object' vs 'into first element
of an object' I mentioned before, but has no ambiguity because everyone
knows strings are handled by pointers to their first characters (IOW,
"strings" is enough context to clear things up).

[snipped an opinion of yours]

Take care

__________________________________

~A Hardware Guy Programming in C~
kiru dot sengal at gmail dot com
__________________________________
 
J

Jean Pierre Daviau

--
Jean Pierre Daviau
--
borland 5.5
windows Xp
asus p4 s533/333/133
http://www.jeanpierredaviau.com
First-chance exception in chap5.9.exe: 0xC0000005: Access Violation.
The thread 0xF0 has exited with code -1073741510 (0xC000013A).
 
J

Jean Pierre Daviau

I must precise it compiles perfectly with Borland bcc32.
Maybe I should use another thread?
-------
MicrosoftVisualC++
Compiling...
chap5_9.c
Linking...

chap5_9.exe - 0 error(s), 0 warning(s)
 
A

Alan Balmer

I must precise it compiles perfectly with Borland bcc32.
Maybe I should use another thread?
-------
MicrosoftVisualC++
Compiling...
chap5_9.c
Linking...

chap5_9.exe - 0 error(s), 0 warning(s)
If you're asking about some code that compiles with VC but not with
BCC, you may have code that violates the standard (bcc was notoriously
lax about such things.) Post it here and we'll look at it.
 
M

Mark McIntyre

It is the Martin Ambuhl's Code three posts up

This is why I am surprised.

Two possibilities
1) martin's code contains deliberate errors for you to fix
2) you typed it wrong
 
A

Alan Balmer

On Thu, 10 Mar 2005 12:43:05 -0500, "Jean Pierre Daviau"

(top post corrected)
It is the Martin Ambuhl's Code three posts up

This is why I am surprised.
Learn to quote enough context so that readers know what you're talking
about. And don't top post.
 
J

Jean Pierre Daviau

Alan Balmer said:
On Thu, 10 Mar 2005 12:43:05 -0500, "Jean Pierre Daviau"

(top post corrected)
Learn to quote enough context so that readers know what you're talking
about. And don't top post.

I start another thread.
" an array of 20 ints "
 
C

CBFalconer

Jean Pierre Daviau wrote:
"Alan Balmer said:
It is the Martin Ambuhl's Code three posts up

Please don't topppost. Your answer goes after, or intermixed with,
the material to which you reply with non-germane material snipped,
and germane material retained.

There is no such thing as 'three posts up'. Every article needs to
stand on its own, and every system decides on its own what to
maintain and what to discard, and how to display them. Without
this context the article tends to be useless. If some code was of
interest, it should have been quoted or a URL given for longer
pieces. If there is a problem with the code it should be
compilable and consist only of standard C. (at least in c.l.c
postings).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

K&R2 Corrections List... 3
The type of argv in K&R2 11
K&R2, exercise 5.5 7
K&R2, exercise 5.4 28
K&R2 exercise 1.17 solution 2
K&R2 section 4.1 example 1
K&R2, 1.5.1 example 4
Ambiguous errata solutions for K&R2 6

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top