473,809 Members | 2,633 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

passing arg char[X][Y] to function expecting (char**)

I've come across the following difficulty, related to questions 6.12,
6.13 and 6.18 in the FAQ, which I am unable to overcome:

void fun(char **array_of_stri ngs, int num_elements);

int main(void)
{
char static_array_of _strings[NUM_STRINGS][MAX_STRING_LEN+ 1];

fun ((char**)&stati c_array_of_stri ngs, NUM_STRINGS);

return 0;
}

This code compiles but is wrong (I get a segmentation fault). How can I
correctly call fun on static_array_of _strings?

I can't modify the prototype of fun() because it also receives "true"
char** (in the sense of dynamically allocated arrays of strings, ie,
both the number of elements in the array as well as the length of each
string are unknown size at compile time).

How can I pass static_array_of _strings to it? The way I read FAQ 6.18
suggests this is impossible and the prototype of fun() would have to
modified to include MAX_STRING_LEN+ 1.
Thank you for any help,

Mack

Nov 14 '05 #1
11 2076
Let me add that, in the mean time, the work-around I have found is

void fun(char **array_of_stri ngs, int num_elements);

int main(void)
{
char static_array_of _strings[NUM_STRINGS][MAX_STRING_LEN+ 1];

/* do other stuff * /

{
char* tmp_array_of_st rings[NUM_STRINGS];
int i = 0;
for (; i < NUM_STRINGS; i++)
tmp_array_of_st rings[i] = static_array_of _strings[i];

fun (tmp_array_of_s trings, NUM_STRINGS);

}

return 0;
}

Since fun() doesn't need to modify the (char*) pointers themselves,
this works. But is there a more elegant way of doing this?

Mack

Nov 14 '05 #2
MackS wrote:
I've come across the following difficulty, related to questions 6.12,
6.13 and 6.18 in the FAQ, which I am unable to overcome:

void fun(char **array_of_stri ngs, int num_elements);
This is the same as

void fun(char* array_of_string s[], int num_elements);
int main(int argc, char* argv[]) {

char static_array_of _strings[NUM_STRINGS][MAX_STRING_LEN+ 1];

fun((char**)&st atic_array_of_s trings, NUM_STRINGS);
This should be something like

char* static_array_of _strings = {"s1", "s2", "s3"};
fun(static_arra y_of_strings, 3);
return 0;
}

This code compiles but is wrong (I get a segmentation fault).
How can I correctly call fun on static_array_of _strings?

I can't modify the prototype of fun() because it also receives "true"
char** (in the sense of dynamically allocated arrays of strings, ie,
both the number of elements in the array
as well as the length of each string
are unknown size at compile time).

How can I pass static_array_of _strings to it?
The way I read FAQ 6.18 suggests this is impossible
and the prototype of fun() would have to modified
to include MAX_STRING_LEN+ 1.


You can write

char* array_of_string s
= (char*)malloc(N UM_STRINGS*size of(char*));
for (size_t i = 0; i < NUM_STRINGS; ++i)
array_of_string s[i] = &(static_array_ of_strings[i][0]);
fun(array_of_st rings, NUM_STRINGS);
free((void*)arr ay_of_strings);

assuming that each array of char in static_array_of _strings
contains at least one '\0'.

If you have a C99 compiler, you could write a wrapper function:

void
fun2(size_t strings, size_t length,
char* static_array_of _strings[strings][length]) {
char* array_of_string s[strings];
for (size_t i = 0; i < strings; ++i)
array_of_string s[i] = &(static_array_ of_strings[i][0]);
fun(array_of_st rings, strings);
}

using variable size arrays.
Nov 14 '05 #3
"MackS" <ma***********@ hotmail.com> writes:
I've come across the following difficulty, related to questions 6.12,
6.13 and 6.18 in the FAQ, which I am unable to overcome:

void fun(char **array_of_stri ngs, int num_elements);

int main(void)
{
char static_array_of _strings[NUM_STRINGS][MAX_STRING_LEN+ 1];

fun ((char**)&stati c_array_of_stri ngs, NUM_STRINGS);

return 0;
}

This code compiles but is wrong (I get a segmentation fault). How can I
correctly call fun on static_array_of _strings?


fun() expects a pointer to an array of pointers.

static_array_of _strings is an array of array of characters; it
contains no pointers.

(Incidentally, the name "static_array_o f_strings" is a bit misleading,
since it isn't static in any of the senses that C uses the term.)

If you want an array of pointers for fun() to chew on, you're going to
have to build it yourself. The workaround you describe in your
followup is actually a good solution.

--
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 14 '05 #4
"E. Robert Tisdale" <E.************ **@jpl.nasa.gov > writes:
[...]
char* array_of_string s
= (char*)malloc(N UM_STRINGS*size of(char*));
char *array_of_strin gs = malloc(NUM_STRI NGS * sizeof *array_of_strin gs);

[...] free((void*)arr ay_of_strings);
free(array_of_s trings);

The cast is useless.

[...] If you have a C99 compiler, you could write a wrapper function:

[...]

And if you don't, much of ERT's other code (which I haven't quoted)
won't compile (unless your compiler implements some C99 features as
extensions).

--
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 14 '05 #5
Keith Thompson wrote:
E. Robert Tisdale writes:
free((void*)arr ay_of_strings);
free(array_of_s trings);

The cast is useless.

cat main.c #include <stdlib.h>

int main(int argc, char* argv[]) {
const
char* p =(const char*)malloc(13 );
free(p);
return 0;
}
gcc -Wall -std=c99 -pedantic -o main main.c

main.c: In function `main':
main.c:6: warning: passing arg 1 of `free' \
discards qualifiers from pointer target type
If you have a C99 compiler,


And if you don't,


get one.

Nov 14 '05 #6
MackS wrote:

I've come across the following difficulty, related to questions
6.12, 6.13 and 6.18 in the FAQ, which I am unable to overcome:

void fun(char **array_of_stri ngs, int num_elements);

int main(void)
{
char static_array_of _strings[NUM_STRINGS][MAX_STRING_LEN+ 1];

fun ((char**)&stati c_array_of_stri ngs, NUM_STRINGS);
return 0;
}

This code compiles but is wrong (I get a segmentation fault).
How can I correctly call fun on static_array_of _strings?
.... snip ...
How can I pass static_array_of _strings to it? The way I read FAQ
6.18 suggests this is impossible and the prototype of fun() would
have to modified to include MAX_STRING_LEN+ 1.


You can't. Fun is expecting a pointer to a pointer to a char. I
see no pointers in static_array_of _strings. (henceforth to be known
as sas)

If you don't need to modify the strings, you could use:

static const char *sas[] = {"string1",
"string2",
"string3",
"laststring "};

and call with fun(&sas, sizeof(sas)/sizeof(sas[0]));

If you do need to modify the strings, create the modifiable strings
and then gather pointers to them in sas.

char string1[MAX_STR_LEN] = "string1";
char string2[MAX_STR_LEN] = "string2";
char string3[MAX_STR_LEN] = "string3";
char laststring[MAX_STR_LEN] = "laststring ";

char *sas[] = {&string1, &string2, &string3, &laststring} ;

--
"If you want to post a followup via groups.google.c om, 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." - Keith Thompson
Nov 14 '05 #7
CBFalconer wrote:
char string1[MAX_STR_LEN] = "string1";
char string2[MAX_STR_LEN] = "string2";
char string3[MAX_STR_LEN] = "string3";
char laststring[MAX_STR_LEN] = "laststring ";

char *sas[] = {&string1, &string2, &string3, &laststring} ;


The address operators in the last initializer seem wrong to me. They
indicate that we have an array of pointers to arrays, which is not
compatible with the left hand side. I'm curious, though: If we wanted to
leave the right hand side as it is, what would the lhs need to look like? I
can't seem to figure it out.
Christian
Nov 14 '05 #8
Christian Kandeler wrote:
char *sas[] = {&string1, &string2, &string3, &laststring} ;

[ ... ]
If we wanted to leave the right hand side as it is, what would the lhs
need to look like? I can't seem to figure it out.


Okay, I remembered there's cdecl. It looks like this:
char (*sas[])[MAX_STR_LEN]
According to the precedence rules, this makes perfect sense, but looking at
it, I never would have guessed that the outer brackets refer to the inner
arrays. I hope I'll never have to use such a construct.
Christian
Nov 14 '05 #9
"E. Robert Tisdale" <E.************ **@jpl.nasa.gov > writes:
Keith Thompson wrote:
E. Robert Tisdale writes:
free((void*)arr ay_of_strings);

free(array_of_s trings);
The cast is useless.

> cat main.c

#include <stdlib.h>

int main(int argc, char* argv[]) {
const
char* p =(const char*)malloc(13 );
free(p);
return 0;
}
> gcc -Wall -std=c99 -pedantic -o main main.c

main.c: In function `main':
main.c:6: warning: passing arg 1 of `free' \
discards qualifiers from pointer target type


So what? There was no const in the previous code; the cast in your
free((void*)arr ay_of_strings);
is indeed useless.

--
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 14 '05 #10

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

Similar topics

58
10190
by: jr | last post by:
Sorry for this very dumb question, but I've clearly got a long way to go! Can someone please help me pass an array into a function. Here's a starting point. void TheMainFunc() { // Body of code... TCHAR myArray; DoStuff(myArray);
5
3027
by: Oeleboele | last post by:
OK, I can't understand this exactly: I have this function: int howdy(void *) I first past this to the function &aCharArray I realized later that this should be aCharArray but... the former version also worked ? I can't understand why that worked. The only thing I can come up with is that the compiler gave me a break (although I did not receive any
7
3021
by: Jeff K | last post by:
Can you pass an int array by reference to a function and modify selective elements? Here is my code: #include <stdio.h> #define COLUMNSIZE 30 #define ASIZE 5 int calcfldpos(int *row, int *column, int *numArray)
6
5586
by: ged | last post by:
Hi, i am a oo (c#) programmer, and have not used javascript for a while and i cant work out how javascript manages its references. Object References work for simple stuff, but once i have an object collection and stanrd using it it starts to fall apart. Clearly there is something about javascript's usage of passing "By ref" that i am not getting. i have had a look on the web and found some examples, but i cant see why my code does not...
3
3497
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
11
7197
by: Bob Yang | last post by:
Hi, I have this in C++ and I like to call it from c# to get the value but I fail. it will be good if you can give me some information. I tried it in VB.net it works but I use almost the same way as VB in C# but it doens't work. c++: (csp2.dll) NoMangle long DLL_IMPORT_EXPORT csp2TimeStamp2Str(unsigned char *Stamp, char *value, long nMaxLength);
8
3510
by: S. | last post by:
Hi all, Can someone please help me with this? I have the following struct: typedef struct { char *name; int age; } Student;
13
3210
by: Andy Baker | last post by:
I am attempting to write a .NET wrapper in C# for an SDK that has been supplied as a .LIB file and a .h header file. I have got most of the functions to work but am really struggling with the functions that require a structure to be passed to them. The function declaration in the .h file is of the form: SDCERR GetConfig(char *name, SDCConfig *cfg); where SDCConfig is a structure defined in the .h file. I am not much of a C (or C#)...
18
3275
by: sanjay | last post by:
Hi, I have a doubt about passing values to a function accepting string. ====================================== #include <iostream> using namespace std; int main() {
0
9721
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
9603
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10640
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
10387
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
9200
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...
1
7662
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
6881
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();...
2
3861
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
3015
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.