473,626 Members | 3,948 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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 2822
On 26 Oct 2005 09:10:23 -0700, in comp.lang.c , ra*****@netscap e.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,"str ing");

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

and

char *buf;

buf = malloc(sizeof(c har)*7);

strcpy(buf,"str ing");

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*****@netscap e.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*)mall oc(10*10000*siz of(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(cha r 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(cha r* 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**)mal loc(10*sizeof(c har*));
for (i=0;i<10;i++)
{
buf[i]=(char*)malloc( 10000*sizeof(ch ar));
}
dosomething(buf )
for (i=0;i<10;i++)
{
free(buf[i]);
}
free(buf);

void dosomething(cha r** 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*****@netscap e.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*****@netscap e.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_Keit h) 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*****@netscap e.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(cha r buf[10][])
{
buf[i][j]

}

shouldn't that be:

void dosomething(cha r *[]);
or// void dosomething(cha r **)
or// void dosomething(cha r [][])

and its subsequent definition:

void dosomething(cha r [][COLS])
or// void dosomething(cha r (*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 multidemensiona l 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*****@netscap e.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
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(cha r 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 #10

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

Similar topics

4
10529
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 sets of character strings from the user. Then I want to run through each element and compare the two strings. If they match I print they match... I'm having a bit of trouble with the actual loop through each array using the pointers and comparing...
4
29112
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 * sizeof(char)); strcpy(cpArray, "A hat is on the mat");
2
6446
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 "*?<>/\|\\" If one of the chars are found, I'd like to replace it with a "-" and then commit the change to the actual file system. I know that a scripting language may be better suited for this, but I'm experimenting with C and I'm trying to...
10
9014
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 think!!). But I want to use malloc. Each string is at most 50 characters long, and there may be zero to thousands of lines. How do I actually start the array? I have seen char **array etc. At first I tried char *array but I think that gives 50...
2
7178
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 *t3 = { "w", "x", "y", "z", NULL }; const char **test = { t1, t2, t3, NULL }; I was wondering whether the is a more elegant way of writing such an
6
2691
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 deperation because when I defined it as char * insert(char table,int cols, char values)
5
3748
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 believe the problem centers around my handling of strings, arrays, pointers and dynamic memory allocation. Here is the problem I'm trying to solve: I want to fill a list box with a list of Project Names from a database (in Palm this is more...
6
2620
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 use these in a linked list for something else I am working on, but I want to make sure my understanding of the concept is correct. For example, from the code below string would equal 'h' after
4
2498
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
8266
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8705
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
8365
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
8505
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7196
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
4092
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4198
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1811
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
2
1511
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.