Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

converting from char [][] to char ** 1

Status
Not open for further replies.

yaronb

Programmer
Jan 6, 2001
13
IL
How can I convert an array of char [20][50] into an "array" of pointers : - char ** ?

Thanks
Yaron.
 
Since a char ** is a pointer to a pointer, you can't do:

char foo[20][50];

char **ptr=&foo[0][0];

You're trying to use ptr to point to the first element of foo. The problem is that the first element of foo is a char and ptr needs to point to a pointer.

And you also can't do this for the same reason:

void bar (char **ptr) { /* ... */ }

/* ... */

char foo[20][50];
bar(&foo[0][0]);

(or any variation)

In other words, there is no pointer in foo to point to.

I'm assuming you want to use a pointer to iterate through the elements of your two dimensional array, perhaps via a function call?

One way to work it out is just to use an ordinary pointer to reference your multidimensional array in the function parameter and also include parameters for the dimension sizes:

#define DIMENSION_X 100
#define DIMENSION_Y 20

/* ... */

void printFoo(char *multiArray,size_t x_len,size_t y_len)
{
size_t x;

for (x=0;x<x_len;++x) {
puts(multiArray + x * y_len);
}
}

/* ... */

char foo[DIMENSION_X][DIMENSION_Y+1];

/* Populate array */

printFoo(&amp;foo[0][0],DIMENSION_X,DIMENSION_Y+1);

/* ... */

HTH,

Russ
bobbitts@hotmail.com
 
First of all - thanks for your answer...
Let me try to explain a little more..

I have an array - foo[30][30] which holds a name of a runable program and some arguments.

The first cell holds the program's name, and the rest holds the program's arguments

I'm trying to use the execvp function (in linux) with this array but when I am trying &quot;execvp(&amp;foo[0],&amp;foo)...I'm getting an error...

I have tried to create a function that converts from this array into the char** pointer - but nothing...

can you help me ?

Yaron
 
Have you tried mallocing a char ** and then just copying the contents of your array over? Something like this:

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

#define X_LENGTH 30
#define Y_LENGTH 30

int main(void)
{
char foo[X_LENGTH][Y_LENGTH+1];
char prog[]=&quot;name_of_prog&quot;;
char **args;
size_t i;

memset(foo,0,sizeof foo);

/* Populate the foo array somewhere in here */

/* Get memory for the pointers */
args=malloc(X_LENGTH * sizeof *args);

if (NULL!=args) {
/* Get memory for and copy over the strings */
for (i=0;i<X_LENGTH;++i) {
if (foo[0]) {
args=malloc(strlen(foo)+1);
if (NULL!=args) {
strcpy(args,foo);
}
} else {
args=NULL;
}
}
}

/* You can call execvp like this */
execvp(prog,args);

/* Sometime later, don't forget to free */
if (NULL!=args) {
for (i=0;args!=NULL;++i) {
free(args);
}
free(args);
}
return 0;
}

If you really /must/ have the program name and the args in the same array, just adjust the indexes and malloc'ed amounts appropriately.

HTH,

Russ
bobbitts@hotmail.com
 
Well, thanks again...
I have managed to create a nice function that translates the array into a pointer :

...
#define ARGC 30
#define SIZE2 50

char matrix[ARGC][SIZE2];
char ** converted_pointer;

char ** convert_array_to_pointers(int argc,char * argv);

int main(void)
{
converted_pointer =
convert_array_to_pointers(ARGC,&amp;matrix[0][0]);
....

}


char ** convert_array_to_pointers(int argc,char * argv)
{
char ** temp_argv = (char**)argv;
int i;

temp_argv = (char**)calloc(argc,sizeof(char*));

for (i=0; i<argc; i++)
{
temp_argv=(char*)calloc(strlen(&amp;argv+1) ,
sizeof(char));
temp_argv = &amp;argv[i*SIZE2];
}
return temp_argv;
}



Yaron.

 
Easy way to copy:
int main ()
{
char a[ARGC][SIZE2] = {some initialization};
char (*b)[SIZE2] = NULL;
int i;

b= (void*) malloc (ARGC*sizeof(char[SIZE2]));
for (i=0; i<ARGC; i++)
memcpy (b,a,sizeof(char[SIZE2]));
return 0;
}
!!!!!!
BUT THIS IS NOT IMOPRTANT. I SEE YOU DOTH DON'T UNDERSTAND ONE IMPORTANT THING:
!!!!!!

int b[10];
b == &amp;b;

Array name in an expression is treated by the compiler as a pointer to the first element of the array (ANSI C Standard, paragraph 6.2.2.1). Array address is already taken with the &amp; operator. So Compiler ignores &quot;&amp;b&quot; and reads it as &quot;b&quot;. &amp;b == b.

so:
my_func(&amp;b);
is the same as
my_func(b);

This can lead to an error when inside of function you are trying to take extra &quot;*&quot; from an argument.
STOP adding extra &quot;&amp;&quot; to stack arrays!!!

Hope this will help and sorry for extra &quot;!!!&quot; :)


 
sorry, correction in code should be:
memcpy (b,a,sizeof(char[SIZE2]));


 
I don't know why it is not showing [ i ]
memcpy ( b [ i ] , a [ i ] , sizeof (char[SIZE2]));

 
It's doing that because tek-tips interprets the i enclosed in brackets as a symbol for italics.

> b= (void*) malloc (ARGC*sizeof(char[SIZE2]));

There is no reason to cast the return value of malloc(). Furthermore, malloc() already returns void * so this cast is superfluous anyway. And why even use the sizeof operator when you can just:

b=malloc(ARGC * SIZE2);

sizeof char is /always/ 1, by definition.

As to your last comment regarding the usage of &amp; in array expressions:

char b[]=&quot;foo&quot;;

myfunc(b);
myfunc(&amp;b);

are /not/ equivalent.

These are equivalent:

myfunc(b);
myfunc(&amp;b[0]);

Assuming that you meant this, I'm quite confused as to why you so strongly discourage using the latter method. In fact, one might argue that using the &amp; operator in such an expression might clarify things in some contexts:

/* Foo modifies s */
void foo (char *s) { /* ... */ }

int main(void)
{
char s[]=&quot;foo&quot;;
foo(&amp;a[0]);
return 0;
}

I think it would be a reasonable argument to say that this clarifies things in the sense that the caller of the function is making it explicit that the address of the first element of the array is being passed to foo(), suggesting that the value of a will be modified in foo(). Yes, foo() states this explicitly, but suppose foo() were somewhere else hidden in a library somewhere?

I also don't understand your point as to dereferencing an extra * from an argument inside of a function because the caller chose to use &amp;a[0] instead of a. The function argument is the same regardless of the syntax the caller uses to call the function.

Russ
bobbitts@hotmail.com
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top