question on passing char ** to fn

  • Follow


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
0
Reply apophis (12) 12/11/2009 8:40:09 AM

On Dec 11, 10:40=A0am, 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];
>
> =A0 =A0 fn(&list);
> =A0 =A0 printf("list 0 %s\n", list[0]);
> =A0 =A0 printf("list 1 %s\n", list[1]);
> =A0 =A0 printf("list 2 %s\n", list[2]);}
>
> void fn(char ***a_list)
> {
> =A0 =A0 strcpy(a_list[0], "one");
> =A0 =A0 strcpy(a_list[1], "two");
> =A0 =A0 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.
0
Reply electricdelta (73) 12/11/2009 9:05:21 AM


In article <hft0h9$v06$2@news.eternal-september.org>,
Eric  <apophis@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
0
Reply ike5 (222) 12/11/2009 9:09:09 AM

Michael Foukarakis wrote:

> 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.

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])
{
     strcpy(a_list[0], "one");
     strcpy(a_list[1], "two");
     strcpy(a_list[2], "three");

 }


0
Reply apophis (12) 12/11/2009 9:31:13 AM

Ike Naar wrote:

> In article <hft0h9$v06$2@news.eternal-september.org>,
> Eric  <apophis@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

Thanks, i went and looked at it and that gave me ideas, see my response to
Michael Foukarakis reply to me below
Thanks
Eric
0
Reply apophis (12) 12/11/2009 9:33:11 AM

In article <hft3h1$v06$3@news.eternal-september.org>,
Eric  <apophis@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.

0
Reply ike5 (222) 12/11/2009 9:48:53 AM

"Eric" <apophis@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 

0
Reply bartc (783) 12/11/2009 11:55:00 AM

Ike Naar wrote:

> In article <hft3h1$v06$3@news.eternal-september.org>,
> Eric  <apophis@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.
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
0
Reply apophis (12) 12/11/2009 8:27:00 PM

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 <apophis@ruler.of.the.night.org>
wrote:

>Ike Naar wrote:
>
>> In article <hft3h1$v06$3@news.eternal-september.org>,
>> Eric  <apophis@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.
>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

-- 
Remove del for email
0
Reply schwarzb3978 (1358) 12/12/2009 1:20:45 AM

"Eric" <apophis@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.


0
Reply regniztar (3128) 12/12/2009 6:28:18 PM

"Malcolm McLean" <regniztar@btinternet.com> writes:

> "Eric" <apophis@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.
0
Reply ben.usenet (6515) 12/12/2009 11:00:08 PM

"Ben Bacarisse" <ben.usenet@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
Reply regniztar (3128) 12/13/2009 12:47:00 PM

11 Replies
47 Views

(page loaded in 0.129 seconds)

Similiar Articles:


















7/27/2012 12:10:23 AM


Reply: