473,796 Members | 2,904 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

char** function parameters

Suppose I have the following function:

void doSomething(cha r** array, int size);

Normally, I would call the function with an array of, say, 3
elements...

char* strs[] = { "str1","str2"," str3" };
doSomething(str s, 3);

That works fine. But if I want to pass it only one char*, I would
think this would work....

char* str = "str1";
doSomething(&st r, 1);

It compiles with a warning about incompatible pointer types, and
needless to say it doesn't behave as I expected. "str1" does not get
passed into the function. What am I doing wrong? How can I pass a
single char* into the function?

Nov 15 '05 #1
12 3061
On Tue, 19 Jul 2005 co***********@h otmail.com wrote:
Suppose I have the following function:

void doSomething(cha r** array, int size);

Normally, I would call the function with an array of, say, 3
elements...

char* strs[] = { "str1","str2"," str3" };
doSomething(str s, 3);

That works fine. But if I want to pass it only one char*, I would
think this would work....

char* str = "str1";
doSomething(&st r, 1);

It compiles with a warning about incompatible pointer types, and
needless to say it doesn't behave as I expected. "str1" does not get
passed into the function. What am I doing wrong? How can I pass a
single char* into the function?


Here is a really simple program. There isn't a compilation problem :

/* Compiled with gcc -Wall -pedantic -O3 */
#include <stdio.h>
#include <stdlib.h>

void f(char **t)
{
printf("%s\n", *t);
}

int main(void)
{
char * str = "str0";
char * tab[] = { "str1", "str2", "str3" };
f(&str);
f(tab);
return EXIT_SUCCESS;
}

Everything goes fine.

So my guess is you're having another kind of problem, which isn't directly
related to passing your pointer.

--
"Je deteste les ordinateurs : ils font toujours ce que je dis, jamais ce
que je veux !"
"The obvious mathematical breakthrough would be development of an easy
way to factor large prime numbers." (Bill Gates, The Road Ahead)
Nov 15 '05 #2
co***********@h otmail.com wrote:
Suppose I have the following function:

void doSomething(cha r** array, int size);

Normally, I would call the function with an array of, say, 3
elements...

char* strs[] = { "str1","str2"," str3" };
doSomething(str s, 3);

That works fine. But if I want to pass it only one char*, I would
think this would work....

char* str = "str1";
doSomething(&st r, 1);

It compiles with a warning about incompatible pointer types, and
needless to say it doesn't behave as I expected. "str1" does not get
passed into the function. What am I doing wrong? How can I pass a
single char* into the function?


I don't see anything wrong with what you posted, can you post a small
but complete program that produces the warning when compiled, and what
exactly is not behaving as you expected?

Robert Gamble

Nov 15 '05 #3
The problem was that I was treating a char[256] as a char*. Here is a
modification of Stephane's program to demonstrate what I want to do:

#include <stdio.h>
#include <stdlib.h>

void f(char **t)
{
printf("%s\n", *t);
}

int main(void)
{
char foo[256];
strcpy(foo, "bar");

f(&foo); /* WRONG */

return EXIT_SUCCESS;
}

The gcc compiler warning is "assignment from incompatible pointer
type," and what prints out when I run the program is garbage.

So is it possible to pass the contents of foo[256] into the function
f()?

Nov 15 '05 #4
co***********@h otmail.com wrote:
The problem was that I was treating a char[256] as a char*. Here is a
modification of Stephane's program to demonstrate what I want to do:

#include <stdio.h>
#include <stdlib.h>

void f(char **t)
{
printf("%s\n", *t);
}

int main(void)
{
char foo[256];
strcpy(foo, "bar");
you need to #include <string.h> for strcpy.
f(&foo); /* WRONG */
Yes, that is wrong. f takes an argument of type pointer to pointer to
char, you are passing pointer to char (foo and &foo decay into a
pointer to the first element of the array, it is the same as &foo[0]).
return EXIT_SUCCESS;
}

The gcc compiler warning is "assignment from incompatible pointer
type," and what prints out when I run the program is garbage.

So is it possible to pass the contents of foo[256] into the function
f()?


You can do this:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void f(char **t)
{
printf("%s\n", *t);
}
int main(void)
{
char foo[256];
char *ptr = foo;
strcpy(foo, "bar");
f(&ptr)
return EXIT_SUCCESS;
}

Robert Gamble

Nov 15 '05 #5
Robert Gamble wrote:

f(&foo); /* WRONG */


Yes, that is wrong. f takes an argument of type pointer to pointer to
char, you are passing pointer to char (foo and &foo decay into a
pointer to the first element of the array, it is the same as &foo[0]).

That's incorrect. &foo is a pointer to the array, so it has type
pointer to array 256 of char, NOT pointer to char.


Brian
Nov 15 '05 #6


Robert Gamble wrote:
co***********@h otmail.com wrote:
The problem was that I was treating a char[256] as a char*. Here is a
modificatio n of Stephane's program to demonstrate what I want to do:

#include <stdio.h>
#include <stdlib.h>

void f(char **t)
{
printf("%s\n", *t);
}

int main(void)
{
char foo[256];
strcpy(foo, "bar");

you need to #include <string.h> for strcpy.

f(&foo); /* WRONG */

Yes, that is wrong. f takes an argument of type pointer to pointer to
char, you are passing pointer to char (foo and &foo decay into a
pointer to the first element of the array, it is the same as &foo[0]).


No, no, no. Please see Question 6.12 in the comp.lang.c
Frequently Asked Questions (FAQ) list

http://www.eskimo.com/~scs/C-faq/top.html

In particular,

- Plain `foo' decays to a pointer to the array's first
element, but `&foo' does not.

- Plain `foo' is the same as `&foo[0]', but `&foo' is
a different thing altogether.

- A proper understanding of the type of `&foo' is the
key to the O.P.'s question.

--
Er*********@sun .com

Nov 15 '05 #7


co***********@h otmail.com wrote:
The problem was that I was treating a char[256] as a char*. Here is a
modification of Stephane's program to demonstrate what I want to do:

#include <stdio.h>
#include <stdlib.h>

void f(char **t)
{
printf("%s\n", *t);
}

int main(void)
{
char foo[256];
strcpy(foo, "bar");

f(&foo); /* WRONG */

Ah, enlightenment dawns. Try something like this:

char *p = foo;
f(&p);
return EXIT_SUCCESS;
}

The gcc compiler warning is "assignment from incompatible pointer
type," and what prints out when I run the program is garbage.

Yes, because the type of &foo is char(*)[256], not char**.
So is it possible to pass the contents of foo[256] into the function
f()?


Try the trick above, see if it helps.

Nov 15 '05 #8
Default User wrote:
Robert Gamble wrote:

f(&foo); /* WRONG */


Yes, that is wrong. f takes an argument of type pointer to pointer to
char, you are passing pointer to char (foo and &foo decay into a
pointer to the first element of the array, it is the same as &foo[0]).

That's incorrect. &foo is a pointer to the array, so it has type
pointer to array 256 of char, NOT pointer to char.


Yup, thanks for the correction.

Robert Gamble

Nov 15 '05 #9
>co***********@ hotmail.com wrote:
[edited for space]
void f(char **t) { printf("%s\n", *t); }
int main(void) {
char foo[256];
strcpy(foo, "bar");
f(&foo); /* WRONG */

In article <11************ **********@g49g 2000cwa.googleg roups.com>
John Bode <jo*******@my-deja.com> wrote:Ah, enlightenment dawns. Try something like this:

char *p = foo;
f(&p);


Indeed. A picture might also help:

foo:
+-----+-----+-----+-----+-----...-----+
| 'b' | 'a' | 'r' | 0 | (junk)... |
+-----+-----+-----+-----+-----...-----+

Here "foo" is an array of size 256 containing "char"s. Note that
there *is no pointer*, there is just the array named "foo", which
occupies 256 bytes.

Inside f(), assuming that **t == 'k' and that the printf()
will print (say) "k2":

t:
+----------------------+ +----------------------+
| *------------------> | * |
+----------------------+ +-----------|----------+
/
/
/
|
v
+-----+-----+-----+
| 'k' | '2' | 0 |
+-----+-----+-----+

Here there are *two* pointers: t, and *t. In this illustration
I drew them both as four bytes long (by making the boxes about
four times the size of the one-byte "char" boxes), but they could
be 2 or 3 or 4 or 8 or 128 bytes, or (on some rather unusual
systems) even just one byte. The important item is that there
are, and *must be*, two pointers -- the one named t, and one that
t points to -- before you can use **t. (The call to printf()
will access (*t)[0], aka **t, and then (*t)[1], and then (*t)[2],
and so on.)

Now, if you just use "foo" in a value context (or write &foo[0]),
the compiler will *construct* a pointer value, pointing to the
first element of the array:

foo:
+-----+-----+-----+-----+-...-+
*------> | 'b' | 'a' | 'r' | 0 | ... |
+-----+-----+-----+-----+-...-+

but this pointer is not (necessarily) stored in memory anywhere,
as it is a mere value, not an object. By adding "char *p = foo",
we create an actual object, so now the above becomes:

p: foo:
+----------+ +-----+-----+-----+-----+-...-+
| *------> | 'b' | 'a' | 'r' | 0 | ... |
+----------+ +-----+-----+-----+-----+-...-+

Now if we call f(&p), we pass to f() a value pointing to the pointer
named "p". f()'s first actions, even before any code inside f()
gets excuted, are to copy that value into an object, the one we
named "t" in f(). In other words, function parameters are really
just ordinary local variables, initialized "by magic" as we begin
executing the function, using the values passed in from the caller.
So now we have "t" (in f()) pointing to "p" (in the main() that I
snipped) pointing to &foo[0] (also in main()), so now the picture
we *wanted* -- t pointing to a pointer that points to the first of
a series of "char"s -- is in fact the picture we *have*.

Whenever you (the generic "you") are struggling with pointers, it
can help to draw pictures. Each named object (variable) is a box
containing a value, or junk if it is uninitialized. If the type
of the object is "pointer to ...", the object contains an arrow.
You need to make sure the arrow points in turn to some other thing
somewhere in memory -- another named object, or perhaps memory
obtained from malloc(). Each chunk of memory in turn contains a
value (or junk), and if the type it is meant to contain is "pointer
to ...", the value is an arrow -- and you have to make the arrow
point somewhere useful, just like last time. You can use a pointer
to write to the thing to which the pointer points, so one
arrow pointing to the first of several uninitialized-memory arrows
can be used to initialize them:

T **ptr = malloc(2 * sizeof *ptr);

produces (assuming malloc() succeeds) this picture:

(pointing off into the weeds)
ptr: /
+---------+ +----/---+---------+
| *---------------> | * | * |
+---------+ +--------+-----\---+
\ (more weeds)

and now you can say "ptr[0] = (some expression)" to set ptr[0],
and likewise with ptr[1]. As before, you can point them to
named variables (of type T), or call malloc() again. The
important thing is to make them point somewhere, and be sure
they still point somewhere valid whenever you use them.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 15 '05 #10

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

Similar topics

12
2052
by: Francis Bell | last post by:
Hello, I've got a program that is reading in a data file of 25 lines. Here is an example of the first two lines: sp/spinnerbait/AAA Lures/Mad Phil/silver/bass/1/1 f/floating minnow/AAA Lures/Skinny Minney/green/bass/0/0/0 In my program, I need to read in each line, BUT, I need to build a different object based upon the characters in the first field. So, I
10
8726
by: JKop | last post by:
Why isn't: int main(int argc, char* argv) { /* ... */ } as: int main(int argc, const char* argv)
5
3679
by: Johnathan Doe | last post by:
Why is is necessary to write a function that allocates memory for, or changes, a pointer to a char array using char** instead of char*? E.g. void modify_string( char** string ) { if( string == NULL ) return;
5
3981
by: jab3 | last post by:
(again :)) Hello everyone. I'll ask this even at risk of being accused of not researching adequately. My question (before longer reasoning) is: How does declaring (or defining, whatever) a variable **var make it an array of pointers? I realize that 'char **var' is a pointer to a pointer of type char (I hope). And I realize that with var, var is actually a memory address (or at
3
2091
by: fernandez.dan | last post by:
My question is about if I should return char* or have a char* as an argument. My basic premise for this function is to return a char* buffer and the size of the buffer to the caller. I know that each of the following works but Stylistic which would be the better approach. Here are my two examples: char* GetBuffer(long* size); or
13
2381
by: poison.summer | last post by:
For instance, I'd like to use unsigned char as an 8-bit integer. Can I use like unsigned char a=0; a++ Thanks a lot!
3
3495
by: ZMan | last post by:
The following code won't compile with gcc version 3.4.2 (mingw-special). How come? Error: cannot convert `char (*)' to `char**' /**********************************************************/ #include <cstdio> #define MAX_WORD_LEN 80 #define MAX_SIZE 1000
48
16987
by: Francine.Neary | last post by:
I've been reflecting on these two types of pointer. As far as I can glean from books, void * and char * are functionally equivalent: the key property of both is that they are pointers that can be faithfully cast to any other pointer type. The only difference seems to be that it is legal to perform arithmetic on a char *, but not on a void *. So if a char * really is just a more functional void *, why would anyone ever use a void * in...
11
5681
by: Siol | last post by:
I'm trying to call a dll function from C# which has the following form: int some_function(int count, char **arg1, char **arg2) Which parameter type I need to use in C# for C++ char** type? I tried byte (array of byte) but I get error "There is no marshaling support for nested arrays." regards
0
9685
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
10244
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10201
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,...
1
7558
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6802
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5454
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
5582
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4130
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
3744
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.