Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

question on passing char ** to fn

1 view
Skip to first unread message

Eric

unread,
Dec 11, 2009, 3:40:09 AM12/11/09
to
Here is what i am trying to do:

void fn(char **a_list);
int main(void)
{
char list[6][32];

fn(list);
printf("list 0 %s\n", list[0]);
printf("list 1 %s\n", list[1]);
printf("list 2 %s\n", list[2]);
}
void fn(char **a_list)
{
strcpy(a_list[0], "one");
strcpy(a_list[1], "two");
strcpy(a_list[2], "three");
}

How do i do this correctly?
I'm not sure how to declare it in the fn prototype or how to
pass the list to fn.
Can someone set me straight here on how this should be done?
Thanks
Eric
--
Msg to ET:
If you get here and there's no planet -
dont ever build a Large Hadron Collider

Michael Foukarakis

unread,
Dec 11, 2009, 4:05:21 AM12/11/09
to
On Dec 11, 10:40 am, Eric <apop...@ruler.of.the.night.org> wrote:
> Here is what i am trying to do:
>
> void fn(char **a_list);
> int main(void)
> {
> char list[6][32];
>
>     fn(&list);

>     printf("list 0 %s\n", list[0]);
>     printf("list 1 %s\n", list[1]);
>     printf("list 2 %s\n", list[2]);}
>
> void fn(char ***a_list)

> {
>     strcpy(a_list[0], "one");
>     strcpy(a_list[1], "two");
>     strcpy(a_list[2], "three");
>
> }

Fixed. The root of your problem: function arguments in C are supplied
by value. To simulate passing by reference, use pointers.

Ike Naar

unread,
Dec 11, 2009, 4:09:09 AM12/11/09
to
In article <hft0h9$v06$2...@news.eternal-september.org>,
Eric <apo...@ruler.of.the.night.org> wrote:
> [snip]

>void fn(char **a_list);
>int main(void)
>{
> char list[6][32];
> fn(list);
> [snip]
>}
> [snip]

>How do i do this correctly?
>I'm not sure how to declare it in the fn prototype or how to
>pass the list to fn.

This is a FAQ; see http://c-faq.com/aryptr/pass2dary.html

Eric

unread,
Dec 11, 2009, 4:31:13 AM12/11/09
to
Michael Foukarakis wrote:

Thanks for the help but that doesnt work.
I get lots of compiler warnings and it segfaults when run
I did get this to work tho (after referring to Ike Naar's response), but is
there a way to avoid the cast and still not get any warnings? I'm using gcc
4.4.1 under linux if it matters.

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

void fn(char a_list[][32]);

int main(void)
{
char list[6][32];

fn((char (*)[32])&list);


printf("list 0 %s\n", list[0]);
printf("list 1 %s\n", list[1]);
printf("list 2 %s\n", list[2]);

return 0;
}

void fn(char a_list[][32])

Eric

unread,
Dec 11, 2009, 4:33:11 AM12/11/09
to
Ike Naar wrote:

Thanks, i went and looked at it and that gave me ideas, see my response to
Michael Foukarakis reply to me below
Thanks
Eric

Ike Naar

unread,
Dec 11, 2009, 4:48:53 AM12/11/09
to
In article <hft3h1$v06$3...@news.eternal-september.org>,

Eric <apo...@ruler.of.the.night.org> wrote:
>I get lots of compiler warnings and it segfaults when run
>I did get this to work tho (after referring to Ike Naar's response), but is
>there a way to avoid the cast and still not get any warnings? I'm using gcc
>4.4.1 under linux if it matters.
>
>#include <stdlib.h>
>#include <stdio.h>
>#include <string.h>
>
>void fn(char a_list[][32]);
>
>int main(void)
> {
> char list[6][32];
>
> fn((char (*)[32])&list);
> printf("list 0 %s\n", list[0]);
> printf("list 1 %s\n", list[1]);
> printf("list 2 %s\n", list[2]);
>return 0;
> }
>
> void fn(char a_list[][32])
>{
> strcpy(a_list[0], "one");
> strcpy(a_list[1], "two");
> strcpy(a_list[2], "three");
>
> }

You don't need the cast; calling fn as

fn(list);

should work fine.

bartc

unread,
Dec 11, 2009, 6:55:00 AM12/11/09
to

"Eric" <apo...@ruler.of.the.night.org> wrote in message
news:hft0h9$v06$2...@news.eternal-september.org...

> Here is what i am trying to do:
>
> void fn(char **a_list);
> int main(void)
> {
> char list[6][32];
>
> fn(list);
> printf("list 0 %s\n", list[0]);
> printf("list 1 %s\n", list[1]);
> printf("list 2 %s\n", list[2]);
> }
> void fn(char **a_list)
> {
> strcpy(a_list[0], "one");
> strcpy(a_list[1], "two");
> strcpy(a_list[2], "three");
> }
>
> How do i do this correctly?
> I'm not sure how to declare it in the fn prototype or how to
> pass the list to fn.
> Can someone set me straight here on how this should be done?

Here's another approach using typedef to create an intermediate 'type'. I
found using what is apparently a one-dimensional array makes it easier to
code:

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

typedef char str32[32];

void fn(str32 *a_list);
int main(void)
{
str32 list[6];

fn(list);
printf("list 0 %s\n", list[0]);
printf("list 1 %s\n", list[1]);
printf("list 2 %s\n", list[2]);
}

void fn(str32 *a_list)


{
strcpy(a_list[0], "one");
strcpy(a_list[1], "two");
strcpy(a_list[2], "three");
}

--
Bartc

Eric

unread,
Dec 11, 2009, 3:27:00 PM12/11/09
to
Ike Naar wrote:

Without the cast this is the result:
gcc -O0 testp.c -o testp
testp.c: In function ‘main’:
testp.c:11: warning: passing argument 1 of ‘fn’ from incompatible pointer
type
testp.c:5: note: expected ‘char (*)[32]’ but argument is of type ‘char (*)
[6][32]’

Here is the source:


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

void fn(char a_list[][32]);

int main(void)
{
char list[6][32];

fn(&list);


printf("list 0 %s\n", list[0]);
printf("list 1 %s\n", list[1]);
printf("list 2 %s\n", list[2]);
return 0;
}

void fn(char a_list[][32])
{
strcpy(a_list[0], "one");
strcpy(a_list[1], "two");
strcpy(a_list[2], "three");

}


Thanks
Eric

Barry Schwarz

unread,
Dec 11, 2009, 8:20:45 PM12/11/09
to
If you are not going to read the responses for details, you won't get
very far in programming. There is no & in Ike's call to fn. Why is
there one in yours?

On Fri, 11 Dec 2009 12:27 -0800, Eric <apo...@ruler.of.the.night.org>
wrote:

--
Remove del for email

Malcolm McLean

unread,
Dec 12, 2009, 1:28:18 PM12/12/09
to

"Eric" <apo...@ruler.of.the.night.org> wrote in message
> char list[6][32];
>
> void fn(char **a_list)

> How do i do this correctly?
>
Multi-dimensional arrays in C are implemented very poorly. They work as
expected as long as the array is in scope, but as soon as you try to pass to
a subroutine, you find ypurself immeshed in difficulties and stupid syntax.

The reason for the problem is that a multi-dimensional array is just a
contiguous area of memeory. It carries no size information with it. So a
subroutine doesn't know the x-dimension of the array, unless you tell it. If
you tell it, you can only pass arrays with an xdimension of precisely the
number ypu specify, which makes subroutines useless for most purposes.

You can semi-solve the problem by creating a multidimensional array which
consists of a list of pointers (eg a char **). However you then can't use
"flat" multi-dimensional arrays, and arrays of pointers are a nuisance to
intialise.

Most experienced C programmers simply use flat arrays and do the
calculations by hand (index = y * width + x). This isn't ideal, but it
works, and gets round the syntax and interfacing problems.


Ben Bacarisse

unread,
Dec 12, 2009, 6:00:08 PM12/12/09
to
"Malcolm McLean" <regn...@btinternet.com> writes:

> "Eric" <apo...@ruler.of.the.night.org> wrote in message
>> char list[6][32];
>>
>> void fn(char **a_list)
>> How do i do this correctly?
>>
> Multi-dimensional arrays in C are implemented very poorly. They work as
> expected as long as the array is in scope, but as soon as you try to pass to
> a subroutine, you find ypurself immeshed in difficulties and stupid
> syntax.

This is not true in C99 which might be available to the OP. I think
C99's syntax for passing variably modified array types is reasonable.
At least, I think it is unreasonable to call the syntax stupid.

> The reason for the problem is that a multi-dimensional array is just a
> contiguous area of memeory. It carries no size information with it. So a
> subroutine doesn't know the x-dimension of the array, unless you tell it. If
> you tell it, you can only pass arrays with an xdimension of precisely the
> number ypu specify, which makes subroutines useless for most
> purposes.

If I understand this, one part is correct. To the OP: you need to
pass a size or sizes so the function knows how big the array is. The
other part, about arrays not carrying any size information is not
true, particularly in C99 where a variable size can be specified.

> You can semi-solve the problem by creating a multidimensional array which
> consists of a list of pointers (eg a char **). However you then can't use
> "flat" multi-dimensional arrays, and arrays of pointers are a nuisance to
> intialise.
>
> Most experienced C programmers simply use flat arrays and do the
> calculations by hand (index = y * width + x). This isn't ideal, but it
> works, and gets round the syntax and interfacing problems.

If circumstances permit, I'd use C99 and pass in the sizes. The
result is reasonably clear.

--
Ben.

Malcolm McLean

unread,
Dec 13, 2009, 7:47:00 AM12/13/09
to
"Ben Bacarisse" <ben.u...@bsb.me.uk> wrote in message

> If circumstances permit, I'd use C99 and pass in the sizes. The
> result is reasonably clear.
>
That's one of the good things about C99. However I can't use it myself, so I
tend to forget about it.


0 new messages