473,387 Members | 1,483 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

arrays of strings and pointers

I have the following code:

char buf[10][10000];

printf("%lp\n", buf);
printf("%lp\n", &buf[0]);
printf("%lp\n", buf[0]);
printf("%lp\n", buf[1]);
printf("%d\n", buf[1]-buf[0]);

The first 3 printfs give the same result and the last 2 show that
buf[1] is 10000 away from buf[0]. Is this the expected result?

I had assumed that the result would have been:

buf:

This should be a pointer to the first of a set of 10 pointers. These
pointers would be accessed by buf[0] ... buf[9]. They would point to
the 10 10000 char strings (which are a single block of memory).

&buf[0]

This should be the same as above. buf[0] is the same as *(buf+0), so
&buf[0] is &(*(buf+0)) which should be just buf.

buf[0]

This should point to the first string. It shouldn't be the same as
&buf[0].

buf[1]

This is as expected 10000 higher than buf[0].

I have a function that takes as its input an array of pointers:

void funct(char **base);

I had assumed that I could just pass buf to it, is it necessary to
create the 10 array of pointers manually ? However, it looks like buf
is of type pointer to a char rather than pointer to a pointer to a char.

Nov 15 '05 #1
36 2780
On 26 Oct 2005 09:10:23 -0700, in comp.lang.c , ra*****@netscape.net
wrote:
buf[0]

This should point to the first string. It shouldn't be the same as
&buf[0].
It is. Think about it.
void funct(char **base);

I had assumed that I could just pass buf to it, is it necessary to
create the 10 array of pointers manually ?
No, this'll work. What are you /actually/ trying to do? Stop trying to
guess whats happening!
However, it looks like buf
is of type pointer to a char rather than pointer to a pointer to a char.


If its defined as above, its an array of arrays of chars.

Note that this isn't the same as either a pointer or a pointer to a
pointer.

--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Nov 15 '05 #2

Mark McIntyre wrote:
However, it looks like buf
is of type pointer to a char rather than pointer to a pointer to a char.


If its defined as above, its an array of arrays of chars.

Note that this isn't the same as either a pointer or a pointer to a
pointer.


Isn't an array and a pointer basically the same once memory has been
allocated etc. ? The difference being that you can't move where the
array base is and also that the array will have memory allocated
automatically. For example, these are basically equivalent (assuming
you ignore run-time and compile time memory allocation differences):

char buf[255];

strcpy(buf,"string");

printf("%c", buf[3]);

and

char *buf;

buf = malloc(sizeof(char)*7);

strcpy(buf,"string");

printf("%c", buf[3]);

You can also use *buf in both cases and that will give you the first
character of the sting.

Anyway, perhaps this equivalence breaks down when you start dealing
with arrays of arrays.

So, I guess the question is, if I define buf as:

char buf[10][10000];

and want to pass it to a function, what should the function prototype
be ? I had assumed that a double array was effectively a pointer to a
pointer.

Also, I assume that it still passes by reference and doesn't copy the
entire array to the function's local variables.

Nov 15 '05 #3
ra*****@netscape.net wrote:
Anyway, perhaps this equivalence breaks down when you start dealing
with arrays of arrays.

So, I guess the question is, if I define buf as:

char buf[10][10000];

and want to pass it to a function, what should the function prototype
be ? I had assumed that a double array was effectively a pointer to a
pointer.

Also, I assume that it still passes by reference and doesn't copy the
entire array to the function's local variables.


yes, this is where you're confused. a multiply dimentioned array is
still just a pointer, not a pointer to a pointer.

char buf[10][10000] allocates the same memory as char buf[10*10000]
which is similar to buf=(char*)malloc(10*10000*sizof(char));

the difference is that if you do char buf[10][10000] the compiler is
smart enough to know how to increment the memory addresses depending on
the two indices.

so you could have

char buf[10][10000];

printf("%c",buf[i][j])

which is equivalent to

char buf[10*10000]
printf("%c",buf[j*10+i]) //i think i got that right - gurus: please
check me on this

so passing a multiply dimensioned array to a function is a pain. here's
how you do it

char buf[10][10000]
dosomething(buf);

void dosomething(char buf[10][])
{
buf[i][j]
}

the compiler needs to know the size of all the dimensions except for
the last one. becasue internally the compiler is doing the j*10+i
step, it's just hiding it from you.

there are two ways around this:

1 - if you actually need to have the stuff in memory ordered as a
matrix (doing fast math stuff), then you can take care of the j*10+i
step yourself

char buf[10*10000];
dosomething(buf);

void dosomething(char* buf)
{
buf[j*10+i]; //same as buf[i][j]
}

2 - if you don't care about speed, then you can do what you were
thinking of with pointers to pointers

char** buf;

buf=(char**)malloc(10*sizeof(char*));
for (i=0;i<10;i++)
{
buf[i]=(char*)malloc(10000*sizeof(char));
}
dosomething(buf)
for (i=0;i<10;i++)
{
free(buf[i]);
}
free(buf);

void dosomething(char** buf)
{
buf[i][j]; //just as you expected
}

gurus: please feel free to correct any misstatements, i think i know
what i'm talking about, but when i read this newsgroup i realize how
much c i don't know.

mike

Nov 15 '05 #4
ra*****@netscape.net wrote:
I have the following code:

char buf[10][10000];
buf:

This should be a pointer to the first of a set of 10 pointers.
buf is an ARRAY. It is not a pointer, or a set of pointers, etc.
Arrays are not pointers. Arrays are a set of adjacent memory
locations for storing objects. Pointers store the address of
other objects. Pointer declarations are indicated by a '*'
symbol (except when it is a function formal parameter).

Please read this newsgroup FAQ, it has a section on arrays
and pointers.
These pointers would be accessed by buf[0] ... buf[9].
That would be:

char *buf[10];

Note the '*' which indicates that we have pointers.
They would point to the 10 10000 char strings (which are a
single block of memory).
That would be:

char *buf[10];
char bufmem[10][10000];
for (int i = 0; i != 10; ++i)
buf[i] = bufmem[i];
buf[0]

This should point to the first string. It shouldn't be the same as
&buf[0].
buf[0] is an array of 10000 chars. The first element of an array
always starts at the same memory location as the entire array.
So that is why you are seeing the same value displayed.
I have a function that takes as its input an array of pointers:

void funct(char **base);

I had assumed that I could just pass buf to it
Buf is not an array of pointers. So you cannot do this.
However, it looks like buf is of type pointer to a char rather
than pointer to a pointer to a char.


buf is of type "array[10] of array[10000] of char".
It can decay to "pointer to array[10000] of char", but not to
"pointer to pointer to char". Read the FAQ for a more detailed
explanation.

Nov 15 '05 #5
ra*****@netscape.net writes:
Mark McIntyre wrote:
>However, it looks like buf
>is of type pointer to a char rather than pointer to a pointer to a char.


If its defined as above, its an array of arrays of chars.

Note that this isn't the same as either a pointer or a pointer to a
pointer.


Isn't an array and a pointer basically the same once memory has been
allocated etc. ? The difference being that you can't move where the
array base is and also that the array will have memory allocated
automatically. For example, these are basically equivalent (assuming
you ignore run-time and compile time memory allocation differences):


No. Arrays are arrays, and pointers are pointers.

The rule is that an expression of array type, in most contexts, is
implicitly converted to a pointer to the array's first element. The
exceptions are when the array expression is the operand of a unary "&"
or "sizeof" operator, or when it's a string literal in an initializer.

Read section 6 of the C FAQ, <http://www.eskimo.com/~scs/C-faq/faq.html>.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #6
ra*****@netscape.net wrote:
Mark McIntyre wrote:
However, it looks like buf
is of type pointer to a char rather than pointer to a pointer to a char.
If its defined as above, its an array of arrays of chars.

Note that this isn't the same as either a pointer or a pointer to a
pointer.


Isn't an array and a pointer basically the same once memory has been
allocated etc. ?


No. Try using sizeof on it. Taking the address also give you a pointer
of a different type. I suggest you read the comp.lang.c FAQ, I'll point
you at a few of the appropriate sections, but you should read rather
more than I will specifically point you at.

Start with http://www.eskimo.com/~scs/C-faq/q6.3.html

<snip>
Anyway, perhaps this equivalence breaks down when you start dealing
with arrays of arrays.
It breaks down with sizeof and & as well.
So, I guess the question is, if I define buf as:

char buf[10][10000];

and want to pass it to a function, what should the function prototype
be ? I had assumed that a double array was effectively a pointer to a
pointer.
No, see http://www.eskimo.com/~scs/C-faq/q6.18.html
Also, I assume that it still passes by reference and doesn't copy the
entire array to the function's local variables.


The array name decays to a pointer to its first element, see
http://www.eskimo.com/~scs/C-faq/q6.4.html, but since pointers and
arrays are different types a pointer to an array and a pointer to a
pointer are different.

Read the rest of section 6, and also read what your text book says about
arrays and pointers (get K&R2 if you don't have a text book, see the
bibliography of the FAQ for the full name).
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 15 '05 #7
char buf[10][10000]
dosomething(buf);

void dosomething(char buf[10][])
{
buf[i][j]

}

shouldn't that be:

void dosomething(char *[]);
or// void dosomething(char **)
or// void dosomething(char [][])

and its subsequent definition:

void dosomething(char [][COLS])
or// void dosomething(char (*ptr_chr)[COLS] )

the point being that a matrix is really a contiguous block of memory
stored in the computer. the abstraction of a deminsion higher than one
is purely a way to simplify it for the programmer. As the computer
obviously cannot do that, it thinks in a linear pattern and the memory
is allocated thus. thus for multidemensional arrays all the compiler
really needs to know is how many elements it needs to read and what
data type it is pointing to.

Nov 15 '05 #8
ra*****@netscape.net wrote:
So, I guess the question is, if I define buf as:

char buf[10][10000];

and want to pass it to a function, what should the function prototype
be ? I had assumed that a double array was effectively a pointer to a
pointer.
That's where you went wrong. It's not a pointer to a pointer. It's
effectively a 'pointer to an array of 10000 char'. Read on for more
explanation of what that means.

The correct prototype is:
void function(char (*buf)[10000]);

An alternative prototype, which means *exactly* the same thing, is:
void function(char buf[][10000]);

Also, I assume that it still passes by reference and doesn't copy the
entire array to the function's local variables.


It doesn't copy the entire array. If you have
char buf[10][10000];
then buf is an array of ten elements. Yes, only ten elements. But what
type does each element have?

Hint: it is NOT a pointer type!

Each element is an array of 10000 chars.

The memory for each of the ten arrays of 10000 chars are packed together
as a single block of 100,000 bytes. There are no pointers stored in memory.

There is a fundamental RULE about arrays, which always applies:

When you use an array, including passing it to a function, what
was an "array" actually becomes a "pointer to the first element
of the array".

What is the first element of your array? It's buf[0].
What type does it have? Array of 10000 char. It is not a pointer.

A pointer to the first element of your array has a special new type:
"pointer to array of 10000 char". You may not have come across the C
syntax for writing such a thing yet. If you wanted to declare 'p' as a
pointer to array of 10000 char, you would write:
char (*p)[10000];

These pointers to arrays are clever beasties. If you add a number to one
of them, it will automatically skip that many blocks of 10000 char, in
effect finding the address of the N'th array of 10000 char. So,
buf + 0 is a pointer to the first block of 10000 char,
buf + 1 is a pointer to the second block of 10000 char,
buf + 2 is a pointer to the third block of 10000 char, etc.

If you dereference it (apply the * operator), it will resolve back into
an array of 10000 char, which will in turn become a pointer to the first
element of that array, ie. a pointer to char.

(buf + 2) is a pointer to the second block of 10000 char

*(buf + 2) is the second block itself, which resolves into
a pointer to the first element of the second block.

However, the pointer *(buf + 2) is never actually stored in the array.
It is *calculated*, probably by adding 2 * 10000 to the base address of
the array.

C has a nice piece of 'syntactical sugar', an unnecessary addition to
the language, which allows you to re-write an expression
*(a + b)
as
a[b]

The two forms are equivalent in *all* situations, no matter whether you
are using arrays, pointers, strings, etc.

So, *(buf + 2) is equivalent to buf[2]

Obviously, the second form is considered more stylish, but you must
understand their equivalence, to understand how C arrays and pointers work.

--
Simon.
Nov 15 '05 #9
Thanks everyone, I understand much better now.

Nov 15 '05 #10
On Wed, 26 Oct 2005 15:49:42 -0700, Mike Deskevich wrote:
[...]
a multiply dimentioned array is
still just a pointer, not a pointer to a pointer.
It's not a pointer, but it does automatically decay to one in most
contexts.

[...] char buf[10][10000];

printf("%c",buf[i][j])

which is equivalent to

char buf[10*10000]
printf("%c",buf[j*10+i]) //i think i got that right - gurus: please ^^^^^^
i*10000+j

[...] void dosomething(char buf[10][])
Won't compile as written.

Try: buf[][10000],
or buf[10][10000]
or (*buf)[10000]

This allows a two-dimensional array with fixed-size second dimension to be
passed without recourse to the two alternatives you later suggested,
although the pointer-to-pointer technique is a common means of dealing
with a variable-size second dimension. C99 provides variable arrays with
further utility when passing array parameters as discussed in detail in a
prior thread.

[For array parameters in function prototypes] the compiler needs to know the size of all the dimensions except for the
last one.

^^^^
first

--
http://members.dodo.com.au/~netocrat
Nov 15 '05 #11
On Wed, 26 Oct 2005 19:27:19 -0700, bitshadow wrote:
[apparently quoting Mike Deskevich's code snippet]
char buf[10][10000]
dosomething(buf);

void dosomething(char buf[10][])
{
buf[i][j]

}

shouldn't that be:

void dosomething(char *[]);
That's OK.
or// void dosomething(char **)
Incompatible with char[10][10000].
or// void dosomething(char [][])
Dubious at best, and if I recall correctly, technically disallowed by the
standard - at least in the function definition. Better to specify at
least the final dimension size as you do below.
and its subsequent definition:

void dosomething(char [][COLS])
or// void dosomething(char (*ptr_chr)[COLS] )
These are fine.
the point being that a matrix is really a contiguous block of memory
stored in the computer.


Correct, but char ** is different and also not necessarily contiguous
(consult the FAQ for details).

--
http://members.dodo.com.au/~netocrat
Nov 15 '05 #12
On 26 Oct 2005 14:46:22 -0700, in comp.lang.c , ra*****@netscape.net
wrote:

Mark McIntyre wrote:
>However, it looks like buf
>is of type pointer to a char rather than pointer to a pointer to a char.
If its defined as above, its an array of arrays of chars.

Note that this isn't the same as either a pointer or a pointer to a
pointer.


Isn't an array and a pointer basically the same once memory has been
allocated etc. ?


No, no, a thousand times no. Please read the FAQ 6.1, 6.2, 6.3 and
following.
char buf[255];
this is an array of 255 chars.
char *buf;
buf = malloc(sizeof(char)*7);
this is a pointer to a block of seven chars.

They're not remotely similar.
Anyway, perhaps this equivalence breaks down when you start dealing
with arrays of arrays.
Well before that......

char buff[255]={0};
char *buf1;
buf = "hello";
buf1 = "hello";
buf[0]="a";
buf1[0]="a";
if I define buf as:

char buf[10][10000];

and want to pass it to a function, what should the function prototype
be ? I had assumed that a double array was effectively a pointer to a
pointer.
The prototype should match the variable - ie char[10][10000].
Optionally, the first dimension may be left empty, and the compiler
will work it out at compile-time.
Also, I assume that it still passes by reference
C /never/ passes by reference, only by value.
and doesn't copy the entire array to the function's local variables.


Thats because it passes the value of the /address/ of the variable.
--
Mark McIntyre
CLC FAQ <http://www.eskimo.com/~scs/C-faq/top.html>
CLC readme: <http://www.ungerhu.com/jxh/clc.welcome.txt>

----== Posted via Newsfeeds.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Nov 15 '05 #13
> or// void dosomething(char **)
Incompatible with char[10][10000].
yes i believe you're right. though a 2d array can be dereferneced with
** such as:
int main(int argc, char **) the number of elements is still missing.
better:

void dosomething(char (*optional_id)[10000]).
an oversight on my part. see below.
or// void dosomething(char [][])


Dubious at best, and if I recall correctly, technically disallowed by
the
standard - at least in the function definition. Better to specify at
least the final dimension size as you do below.

for the prototype the num of elements needs to be indicated as you
said -which is the inconvenience of it all as that necesscitate a
physic ability, for the definition obvioulsy a identifier must be
included. however this was done to show the prototype.

Nov 15 '05 #14
[blockquote]
char buf[10][10000] allocates the same memory as char buf[10*10000]

which is similar to buf=(char*)malloc(10*10000*sizof(char));
[/blockquote]

just wanted to add, the first statement was correcnt in the allocation
of memory, however, we are coding in C and malloc doesn't need to be
cast in C. C++ yes, not here.
also the *sizeof(char) is redundant. malloc allocates bytes which
defaults to the sizof char so 10 * 10000 is sufficient.

Nov 15 '05 #15
On Thu, 27 Oct 2005 11:16:17 -0700, bitshadow wrote:
[quoting Netocrat, in turn
quoting bitshadow]
or// void dosomething(char **)

Incompatible with char[10][10000].

yes i believe you're right. though a 2d array can be dereferneced with
** such as:
int main(int argc, char **) the number of elements is still missing.


Sure, you can dereference a 2d array using **, because an array
decays to a pointer in that context. They're different and incompatible
types though. What's passed in to main as the second argument
uses explicit pointers (and requires more memory) whereas char[X][Y] uses
implicit pointers only, and provides necessarily contiguous memory.

Check out the FAQ if that sounds a little vague.

[...]
--
http://members.dodo.com.au/~netocrat
Nov 15 '05 #16
Simon Biber <ne**@ralmin.cc> writes:
[...]
There is a fundamental RULE about arrays, which always applies:

When you use an array, including passing it to a function, what
was an "array" actually becomes a "pointer to the first element
of the array".


No, it doesn't always apply.

It's clearer to say that it's implicitly converted to a pointer, not
that it "becomes" a pointer (the array is still there, after all).

An expression of array type is implicitly converted to a pointer to
its first element *unless* it's the operand of a unary "&" or "sizeof"
operator, or it's a string literal in an initializer.

<HINT>This Question is Asked Frequently.</HINT> (See section 6.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #17
"bitshadow" <ca********@yahoo.com> writes:
[blockquote]
char buf[10][10000] allocates the same memory as char buf[10*10000]

which is similar to buf=(char*)malloc(10*10000*sizof(char));
[/blockquote]
The correct way to quote is to use a "> " prefix on each quoted line,
and to provide an attribution line to indicate who is being quoted.
See nearly every article in this newsgroup for examples. Google makes
this gratuitously difficult, which is why the following advice has
been offered here over 1000 times:

If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.

And please complain to Google about their broken interface.
just wanted to add, the first statement was correcnt in the allocation
of memory, however, we are coding in C and malloc doesn't need to be
cast in C. C++ yes, not here.
also the *sizeof(char) is redundant. malloc allocates bytes which
defaults to the sizof char so 10 * 10000 is sufficient.


It's also possible that the expression 10*10000 could overflow (it's
of type int, which needn't be able to represent values greater than
32767).

The malloc() is similar to the array declaration in that it allocates
(or attempts to allocate) the same amount of space, and the variable
name is spelled the same way. It's very different in that
char buf[10[[10000];
declares buf as an array object, whereas
buf = malloc(whatever);
implies that buf is a pointer. C FAQ, section 6.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #18
"bitshadow" <ca********@yahoo.com> writes:
or// void dosomething(char **)

Incompatible with char[10][10000].
yes i believe you're right. though a 2d array can be dereferneced with
** such as:
int main(int argc, char **) the number of elements is still missing.


No, argv is not a 2d array; it's a pointer-to-pointer-to-char. The
actual value passed is going to be a pointer to the first element of
an array of pointers to char; each element of the array points to the
first character of a string (or has the value NULL).

There are at least four different ways to implement a data structure
that acts like 2-dimensional array.

You can declare an actual array:
int arr1[10][10];
but that's of fixed size (even if it's a VLA, the size can't change
once the object is created).

If you want a variable number of fixed-size arrays, you can declare
an array of pointers:
int *arr2[10];

If you want a fixed number of variable-size arrays, you can declare
a pointer to an array:
int (*arr3)[10];

If you want maximum flexibility, you can declare a pointer-to-pointer:
int **arr4;

For arr2, arr3, and arr4, you have to do your own memory management.
For arr4, you have to allocate an array of pointers *and* multiple
arrays of int, one for each row of the 2d-array-like data structure.

Now remember that the indexing operator x[y] actually operates on
pointers, not necessarily on arrays; it's equivalent to *(x+y). It
works on arrays because an array name is (usually) implicitly
converted to a pointer.

The declarations of arr1, arr2, arr3, and arr4 create four very
different things: a true two-dimensional array (actually an array of
arrays), an array of pointers, a pointer to an array, and a pointer to
a pointer. In a non-C-like language, these would have very little in
common. In C, they still have very little in common. But because of
the implicit conversion of arrays to pointers, the following
expressions (assuming a and b are integers) are *all* valid:

arr1[a][b]
arr2[a][b]
arr3[a][b]
arr4[a][b]

You can *sometimes* get away with using arrays and pointers in C
without understanding all of this, but if you want to program
effectively and understand what your code is doing, you should
understand how all this stuff actually works under the hood.

Section 6 of the C FAQ is a good starting point.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #19
Keith Thompson <ks***@mib.org> writes:
[snip]
There are at least four different ways to implement a data structure
that acts like 2-dimensional array. [] int arr1[10][10]; [] int *arr2[10]; [] int (*arr3)[10]; [] int **arr4;


Hey Keith,

I like what you wrote here. Just one suggestion: if you
have occasion to post it again, start with

int arr1[10][20];

so subsequent declarations for arr2 and arr3 can make
it more obvious which dimension corresponds to which.

Nov 15 '05 #20
Keith Thompson wrote:
It's also possible that the expression 10*10000 could overflow (it's
of type int, which needn't be able to represent values greater than
32767). True, but doesn't C allow the int type to change up to long long - if
the compiler supports it - to accomadate the int?
The malloc() is similar to the array declaration in that it allocates
(or attempts to allocate) the same amount of space, and the variable
name is spelled the same way. It's very different in that
char buf[10[[10000];
declares buf as an array object, whereas
buf = malloc(whatever);
implies that buf is a pointer. C FAQ, section 6.


thanks, i knew that ;). as for the FAQ you mean section 2? cause unless
i'm mistaken section 6 deals with the preprocessor.

also thanks for the pointers - no pun intended - on how to use google
groups. its more than annoying actually.

Nov 15 '05 #21
"bitshadow" <ca********@yahoo.com> writes:
Keith Thompson wrote:
It's also possible that the expression 10*10000 could overflow (it's
of type int, which needn't be able to represent values greater than
32767). True, but doesn't C allow the int type to change up to long long - if
the compiler supports it - to accomadate the int?


No. An unsuffixed decimal integer constant such as 10 or 10000 has
the first of the following types that can represent its value:
int
long int
long long int

Since int can represent values up to at least 32767, both 10 and 10000
are guaranteed to be of type int. If their product, 10*10000, doesn't
fit in an int, an overflow results. (The list of types applies only
to individual integer constants, not to larger expressions.)

It's important to remember that the type of an expression in C is
determined by the expression itself, not by the context in which it
appears.
The malloc() is similar to the array declaration in that it allocates
(or attempts to allocate) the same amount of space, and the variable
name is spelled the same way. It's very different in that
char buf[10[[10000];
declares buf as an array object, whereas
buf = malloc(whatever);
implies that buf is a pointer. C FAQ, section 6.


thanks, i knew that ;). as for the FAQ you mean section 2? cause unless
i'm mistaken section 6 deals with the preprocessor.


Section 6 of the C FAQ (found at <http://www.eskimo.com/~scs/C-faq/faq.html>)
is "Arrays and Pointers". Section 10 is "C Preprocessor".
also thanks for the pointers - no pun intended - on how to use google
groups. its more than annoying actually.


You're welcome. It's nice to know that my campaign actually has some
effect.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #22
Keith Thompson wrote:
Simon Biber <ne**@ralmin.cc> writes:
[...]
There is a fundamental RULE about arrays, which always applies:

When you use an array, including passing it to a function, what
was an "array" actually becomes a "pointer to the first element
of the array".

No, it doesn't always apply.

It's clearer to say that it's implicitly converted to a pointer, not
that it "becomes" a pointer (the array is still there, after all).

An expression of array type is implicitly converted to a pointer to
its first element *unless* it's the operand of a unary "&" or "sizeof"
operator, or it's a string literal in an initializer.


Yes, I didn't think it necessary to mention that, but perhaps I should have.

--
Simon.
Nov 15 '05 #23
On 2005-10-28, Keith Thompson <ks***@mib.org> wrote:
also thanks for the pointers - no pun intended - on how to use
google groups. its more than annoying actually.


You're welcome. It's nice to know that my campaign actually
has some effect.


I applaud your campaign to teach people using Google Groups how
to post properly to usenet. My only criticism of the effort is
that the language you use in the standard response is prejudicial
instead of simply instructional. If you removed the references to
Google's brokeness, I think it would be improved.

But you're doing the dirty work, so do it the way you like. ;-)

--
Neil Cerutti
Nov 15 '05 #24
Neil Cerutti wrote:

<snip>
I applaud your campaign to teach people using Google Groups how
to post properly to usenet. My only criticism of the effort is
that the language you use in the standard response is prejudicial
instead of simply instructional. If you removed the references to
Google's brokeness, I think it would be improved.
Part of what we are trying for is enough people complaining to Google
that they actually fix it.
But you're doing the dirty work, so do it the way you like. ;-)


:-)
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
Nov 15 '05 #25
Flash Gordon wrote:
Neil Cerutti wrote:

<snip>
I applaud your campaign to teach people using Google Groups how
to post properly to usenet. My only criticism of the effort is
that the language you use in the standard response is prejudicial
instead of simply instructional. If you removed the references to
Google's brokeness, I think it would be improved.


Part of what we are trying for is enough people complaining to Google
that they actually fix it.


It also lays off the blame from the user to the tool, which can make it
a bit easier to swallow (theoretically).

Brian
Nov 15 '05 #26
On 28 Oct 2005 15:07:37 +0200, Neil Cerutti <le*******@email.com>
wrote:
I applaud your campaign to teach people using Google Groups how
to post properly to usenet. My only criticism of the effort is
that the language you use in the standard response is prejudicial
Nope, it's judicial, but not prejudicial.
instead of simply instructional. If you removed the references to
Google's brokeness, I think it would be improved.

--
Al Balmer
Balmer Consulting
re************************@att.net
Nov 15 '05 #27
Neil Cerutti <le*******@email.com> writes:
On 2005-10-28, Keith Thompson <ks***@mib.org> wrote:
also thanks for the pointers - no pun intended - on how to use
google groups. its more than annoying actually.
You're welcome. It's nice to know that my campaign actually
has some effect.


I applaud your campaign to teach people using Google Groups how
to post properly to usenet. My only criticism of the effort is
that the language you use in the standard response is prejudicial
instead of simply instructional. If you removed the references to
Google's brokeness, I think it would be improved.


I didn't prejudge anything. I looked at Google's interface and
concluded that it's broken. This entire mess is Google's fault, and
they've stubbornly refused to fix it.
But you're doing the dirty work, so do it the way you like. ;-)


Thanks.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #28
On 2005-10-28, Alan Balmer <al******@att.net> wrote:
On 28 Oct 2005 15:07:37 +0200, Neil Cerutti <le*******@email.com>
wrote:
I applaud your campaign to teach people using Google Groups how
to post properly to usenet. My only criticism of the effort is
that the language you use in the standard response is
prejudicial


Nope, it's judicial, but not prejudicial.


Point taken. I only meant that the instructions favor a
preconceived notion, i.e., that Google's interface is broken.
_The C++ Programming Language_ by Stroustrup would be diminished
if legitimate bashing of other programming languages was
included.

--
Neil Cerutti
Nov 15 '05 #29
On 2005-10-28, Neil Cerutti <le*******@email.com> wrote:
Point taken. I only meant that the instructions favor a
preconceived notion, i.e., that Google's interface is broken.


It's not a preconceived notion. It's a fact supported by
observational evidence.

now, from a philosophical point of view, one _could_ challenge the
idea that an interface which behaves in that way is necessarily
broken... but then one would be wrong.
Nov 15 '05 #30
Neil Cerutti <le*******@email.com> writes:
On 2005-10-28, Alan Balmer <al******@att.net> wrote:
On 28 Oct 2005 15:07:37 +0200, Neil Cerutti <le*******@email.com>
wrote:
I applaud your campaign to teach people using Google Groups how
to post properly to usenet. My only criticism of the effort is
that the language you use in the standard response is
prejudicial
Nope, it's judicial, but not prejudicial.


Point taken. I only meant that the instructions favor a
preconceived notion, i.e., that Google's interface is broken.


It is not a preconceived notion. It's a conclusion reached by
observing Google's interface and its effects on this newsgroup.

Before they rolled out their current interface, any prejudice I had
would have been in favor of Google. I like Google, and I'm impressed
by what they've accomplished. The brokenness of their current
groups.google.com interface was an unpleasant surprise.
_The C++ Programming Language_ by Stroustrup would be diminished
if legitimate bashing of other programming languages was
included.


I don't think that's a good analogy. We're critiquing the Google
interface. A critique of a programming language would inevitably
include criticisms of that language.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #31
On 2005-10-28, Keith Thompson <ks***@mib.org> wrote:
Neil Cerutti <le*******@email.com> writes:
On 2005-10-28, Alan Balmer <al******@att.net> wrote:
On 28 Oct 2005 15:07:37 +0200, Neil Cerutti <le*******@email.com>
wrote:
I applaud your campaign to teach people using Google Groups
how to post properly to usenet. My only criticism of the
effort is that the language you use in the standard response
is prejudicial

Nope, it's judicial, but not prejudicial.


Point taken. I only meant that the instructions favor a
preconceived notion, i.e., that Google's interface is broken.


It is not a preconceived notion. It's a conclusion reached by
observing Google's interface and its effects on this newsgroup.


I just meant it in the sense of being decided beforehand, not in
the sense of being conceived without evidence or through
prejudice. It was not a fair word to use; I probably chose it for
the negative connotations, and now look like a jerk claiming I
didn't mean it in a negative way. Sorry for the cheap rhetorical
trick, which several people have properly called me on.

--
Neil Cerutti
Nov 15 '05 #32
On 28 Oct 2005 20:31:55 +0200, Neil Cerutti <le*******@email.com>
wrote:
On 2005-10-28, Alan Balmer <al******@att.net> wrote:
On 28 Oct 2005 15:07:37 +0200, Neil Cerutti <le*******@email.com>
wrote:
I applaud your campaign to teach people using Google Groups how
to post properly to usenet. My only criticism of the effort is
that the language you use in the standard response is
prejudicial
Nope, it's judicial, but not prejudicial.


Point taken. I only meant that the instructions favor a
preconceived notion, i.e., that Google's interface is broken.


I'd call that an observation, not a preconceived notion ;-) It
previously worked adequately, and now it doesn't.
_The C++ Programming Language_ by Stroustrup would be diminished
if legitimate bashing of other programming languages was
included.

--
Al Balmer
Balmer Consulting
re************************@att.net
Nov 15 '05 #33
Neil Cerutti <le*******@email.com> writes:
On 2005-10-28, Keith Thompson <ks***@mib.org> wrote:
Neil Cerutti <le*******@email.com> writes:
On 2005-10-28, Alan Balmer <al******@att.net> wrote:
On 28 Oct 2005 15:07:37 +0200, Neil Cerutti <le*******@email.com>
wrote:
>I applaud your campaign to teach people using Google Groups
>how to post properly to usenet. My only criticism of the
>effort is that the language you use in the standard response
>is prejudicial

Nope, it's judicial, but not prejudicial.

Point taken. I only meant that the instructions favor a
preconceived notion, i.e., that Google's interface is broken.


It is not a preconceived notion. It's a conclusion reached by
observing Google's interface and its effects on this newsgroup.


I just meant it in the sense of being decided beforehand, not in
the sense of being conceived without evidence or through
prejudice. It was not a fair word to use; I probably chose it for
the negative connotations, and now look like a jerk claiming I
didn't mean it in a negative way. Sorry for the cheap rhetorical
trick, which several people have properly called me on.


Ok, fair enough.

I still don't understand what you mean by "decided beforehand", but we
can just drop it if you like.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #34
On 2005-10-28, Keith Thompson <ks***@mib.org> wrote:
Neil Cerutti <le*******@email.com> writes:
I still don't understand what you mean by "decided beforehand",
but we can just drop it if you like.


Decided before writing the instructions. The instructions do
actually contain some argument for the broken conclusion though,
so now I don't know what I mean either. ;-)

--
Neil Cerutti
Nov 15 '05 #35
On Thu, 27 Oct 2005 21:11:15 GMT, Keith Thompson <ks***@mib.org>
wrote:
<snip>
There are at least four different ways to implement a data structure
that acts like 2-dimensional array. <snip> If you want a variable number of fixed-size arrays, you can declare
an array of pointers:
int *arr2[10];

If you want a fixed number of variable-size arrays, you can declare
a pointer to an array:
int (*arr3)[10];
You have the antecedent clauses swapped. (Or both the consequents and
code, which I assumed is less likely.)
If you want maximum flexibility, you can declare a pointer-to-pointer:
int **arr4;

For arr2, arr3, and arr4, you have to do your own memory management.
For arr4, you have to allocate an array of pointers *and* multiple
arrays of int, one for each row of the 2d-array-like data structure.

For array-of-pointer (2) and pointer-to-pointers (4) you don't have to
allocate each row separately; you can allocate one big chunk, or even
several midsized ones, and set pointers into them. But only if you
don't need to independently change the size(s) of rows that are
allocated together; and you must either know a priori or keep track of
which ones are the original allocations (thus) to be free'd. This is
enough of a pain that I would usually stick with the simple way.

<snip rest including pointer to FAQ section 6> concur.

- David.Thompson1 at worldnet.att.net
Nov 15 '05 #36
Dave Thompson <da*************@worldnet.att.net> writes:
On Thu, 27 Oct 2005 21:11:15 GMT, Keith Thompson <ks***@mib.org>
wrote:
<snip>
There are at least four different ways to implement a data structure
that acts like 2-dimensional array.

<snip>
If you want a variable number of fixed-size arrays, you can declare
an array of pointers:
int *arr2[10];

If you want a fixed number of variable-size arrays, you can declare
a pointer to an array:
int (*arr3)[10];

You have the antecedent clauses swapped. (Or both the consequents and
code, which I assumed is less likely.)


You're right, I goofed. Thanks for catching it.
If you want maximum flexibility, you can declare a pointer-to-pointer:
int **arr4;

For arr2, arr3, and arr4, you have to do your own memory management.
For arr4, you have to allocate an array of pointers *and* multiple
arrays of int, one for each row of the 2d-array-like data structure.

For array-of-pointer (2) and pointer-to-pointers (4) you don't have to
allocate each row separately; you can allocate one big chunk, or even
several midsized ones, and set pointers into them. But only if you
don't need to independently change the size(s) of rows that are
allocated together; and you must either know a priori or keep track of
which ones are the original allocations (thus) to be free'd. This is
enough of a pain that I would usually stick with the simple way.


I was assuming a potential need to reallocate the individual chunks,
or to allocate them separately rather than all at once. Certainly you
can sometimes optimize by allocating multiple chunks together, if you
have enough information.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #37

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: agent349 | last post by:
First off, I know arrays can't be compared directly (ie: if (arrary1 == array2)). However, I've been trying to compare two arrays using pointers with no success. Basically, I want to take three...
4
by: Robert | last post by:
Hi, How can i resize an array of strings to add more? This is an example i just downloaded from a website: char *cpArray; int i; for (i = 0; i < 10; i++) cpArray = (char *)malloc(20 *...
2
by: hokieghal99 | last post by:
I wish to place all files and directories that are within a user defined path (on a Linux x86 PC) into some type of array and then examine those items for the existence of certain charaters such as...
10
by: Ian Todd | last post by:
Hi, I am trying to read in a list of data from a file. Each line has a string in its first column. This is what i want to read. I could start by saying char to read in 1000 lines to the array( i...
2
by: Steve | last post by:
I want an initializer for an array of pointers to arrays of strings. So I can do something like this: const char *t1 = { "a", "b", "c", NULL }; const char *t2 = { "p", "q", NULL }; const char...
6
by: Ruben | last post by:
I'm trying to pass an array of string to a function without knowing how many strings I have beforehand. I've defined one functions as char * insert(char table,int cols, char values); out of...
5
by: swarsa | last post by:
Hi All, I realize this is not a Palm OS development forum, however, even though my question is about a Palm C program I'm writing, I believe the topics are relevant here. This is because I...
6
by: bwaichu | last post by:
Is my understanding of the allocation of these correct? I used fixed sized allocations for the example below, so I realize there is some optimization that can be done to those. I would like to...
4
by: Christian Maier | last post by:
Hi After surfing a while I have still trouble with this array thing. I have the following function and recive a Segmentation fault, how must I code this right?? Thanks Christian Maier
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.