Passing char[][] as argument | Newbie | | Join Date: Oct 2008
Posts: 22
| |
I'm trying to pass this array - char files[num][maxLen+8];
like this - if(fillFileArr(&(files[0][0]), &(buf[0]), num)==-1)
-
return -1;
to this function - int fillFileArr(char ** files, char * buf, int num) {
-
int word=0, wordPos=0, bufferPos=0;
-
while(word<num && buf[bufferPos]!='\0') {
-
if(word==0 && wordPos==0 && bufferPos==0)
-
printf("! ");
-
if(buf[bufferPos]=='\n') {
-
if(buf[bufferPos+1]!='\0')
-
printf("\n! ");
-
-
-
word++;
-
wordPos=0;
-
} else {
-
printf("files[%d][%d] = %c\n", word, wordPos, buf[bufferPos]);
-
files[word][wordPos++] = buf[bufferPos];
-
printf("%c",buf[bufferPos]);
-
}
-
bufferPos++;
-
}
-
return 0;
-
}
but it results in a seg fault... I guess there's a pointer mistake somewhere, but can't really find it..
Would someone please point it out?
Thanks in advance
|  | AdministratorVoR | | Join Date: Feb 2006 Location: South West UK
Posts: 6,168
| | | re: Passing char[][] as argument
&(files[0][0]) has type char *
but
int fillFileArr(char ** files, char * buf, int num)
is a function expecting char **. Actually I am rather surprised that this doesn't actually produce any compiler warnings.
Also files[word][wordPos++] = buf[bufferPos]; is trying to pretend that files inside the function is still a char [][] but it isn't.
Is maxLen fixed? (i.e. a constant) if so you could try
int fillFileArr(char (*files)[maxLen+8], char * buf, int num)
otherwise you probably need to pass in a char * and the 2 dimensions of the array pointed to.
| | Needs Regular Fix | | Join Date: Sep 2007 Location: The Netherlands
Posts: 427
| | | re: Passing char[][] as argument
if(fillFileArr(&(files[0][0]), &(buf[0]), num)==-1) is wrong: is &(files[0][0]) of type char ** ? I suggest you read this.
EDIT: Oops, Banfa was faster.
| | Moderator | | Join Date: Mar 2007 Location: North Bend Washington USA
Posts: 5,366
| | | re: Passing char[][] as argument
It probably here: -
if(fillFileArr(&(files[0][0]), &(buf[0]), num)==-1)
-
return -1;
-
Your function needs a char** and you have provided a char*.
And I would like to know what compiler you are using as your code does not compile. My compiler complains about &files[0][0] not being a char**.
Also, your function parameter for this array is not a char**. A char** is not the address of an array. In your case the array is: -
char files[num][maxLen+8];
-
so the function argument has to be a pointer to an array of maxLen+8: -
int fillFileArr(char (* files)[maxLen+8], char * buf, int num) {
-
etc...
-
Read this: http://bytes.com/forum/thread772412.html.
| | Newbie | | Join Date: Oct 2008
Posts: 22
| | | re: Passing char[][] as argument Quote:
Originally Posted by weaknessforcats It probably here: -
if(fillFileArr(&(files[0][0]), &(buf[0]), num)==-1)
-
return -1;
-
Your function needs a char** and you have provided a char*. Ok Quote:
And I would like to know what compiler you are using as your code does not compile. My compiler complains about &files[0][0] not being a char**.
gcc/cc in Xcode for OSX Leopard Quote:
Also, your function parameter for this array is not a char**. A char** is not the address of an array. In your case the array is: -
char files[num][maxLen+8];
-
so the function argument has to be a pointer to an array of maxLen+8: -
int fillFileArr(char (* files)[maxLen+8], char * buf, int num) {
-
etc...
-
Read this: http://bytes.com/forum/thread772412.html.
I'll check it out and look to it if I have the time - sort of in a hurry on this project, and this particular piece is not that critical...
Thanks for all the help - I'll look into this again when I have the time :)
| | Newbie | | Join Date: Oct 2008
Posts: 22
| | | re: Passing char[][] as argument
Ok... I have made another atempt on the previously mentioned function - this time I hope it might work with some tweaking - different from the last code, which seemed impossible to implement :)
What I want to do is:
Take a pointer to a string and and some numbers giving the dimensions of the text (longest words and number of words) which is needed to allocate enogh memory for all the data. Then I will allocate memory, fill the pointers with data and return the char **. - char ** fillFileArr(char * buf, int num, int maxLen) {
-
char ** arr = (char *) malloc(num);
-
int y;
-
-
for(y=0; y<num; y++) {
-
arr[y] = (char *) malloc(maxLen+1);
-
}
-
-
int word=0, wordPos=0, bufferPos=0;
-
while(word<num && buf[bufferPos]!='\0') {
-
if(word==0 && wordPos==0 && bufferPos==0)
-
printf("! ");
-
if(buf[bufferPos]=='\n') {
-
arr[word][wordPos] = '\0';
-
-
if(buf[bufferPos+1]!='\0')
-
printf("\n! ");
-
-
word++;
-
wordPos=0;
-
} else {
-
arr[word][wordPos++] = buf[bufferPos];
-
printf("%c", buf[bufferPos]);
-
}
-
bufferPos++;
-
}
-
-
return arr;
-
}
According to this article [ http://stackoverflow.com/questions/4...arguments-in-c] (which my code is to a certain degree based upon) it should be possible to later on do a
on this data - right?
Yours sincerely
| | Needs Regular Fix | | Join Date: Sep 2007 Location: The Netherlands
Posts: 427
| | | re: Passing char[][] as argument
Check your types: is (char *) malloc(num) of type char** on line 2? Did you try to compile this code?
| | Newbie | | Join Date: Oct 2008
Posts: 22
| | | re: Passing char[][] as argument Quote:
Originally Posted by arnaudk Check your types: is (char *) malloc(num) of type char** on line 2? Did you try to compile this code? I tried both casting the malloc to (char **), (char *) and nothing - same result...
| | Expert | | Join Date: Mar 2008 Location: Naperville, Illinois U.S.
Posts: 831
| | | re: Passing char[][] as argument Quote:
Originally Posted by krreks I tried both casting the malloc to (char **), (char *) and nothing - same result... And what result was that?
By the way, I suggest you turn on all of the compiler warning options. Line 6 of post #6 should have provoked a compiler warning. You should resolve all compiler warnings before you try to execute your program.
| | Needs Regular Fix | | Join Date: Sep 2007 Location: The Netherlands
Posts: 427
| | | re: Passing char[][] as argument Quote:
Originally Posted by krreks I tried both casting the malloc to (char **), (char *) and nothing - same result... But one of those is wrong. You'll probably save yourself some time if you read that article on arrays mentioned above. The correct form should be
char ** arr = (char **) malloc(num*(maxLen+1)); now you have an array big enough to hold num strings of maxLen characters (plus '\0'), and drop the malloc() on line 6.
| | Newbie | | Join Date: Oct 2008
Posts: 22
| | | re: Passing char[][] as argument Quote:
Originally Posted by donbock And what result was that?
By the way, I suggest you turn on all of the compiler warning options. Line 6 of post #6 should have provoked a compiler warning. You should resolve all compiler warnings before you try to execute your program. It was late last night but as far as I remember i got seg faults in all three cases. I'm compiling with - gcc -o server server.c helpers.o protocol.o -I. -DDEBUG -g -Wall
|  | AdministratorVoR | | Join Date: Feb 2006 Location: South West UK
Posts: 6,168
| | | re: Passing char[][] as argument Quote:
Originally Posted by arnaudk The correct form should be
char ** arr = (char **) malloc(num*(maxLen+1)); Actually in C the correct form avoiding unrequired casts is
char ** arr = malloc(num*(maxLen+1));
and in C++ the correct form is
char ** arr = new char *[num*(maxLen+1)];
assuming you want num*(maxLen+1) pointers although I would have thought that num pointers would be enough.
| | Needs Regular Fix | | Join Date: Sep 2007 Location: The Netherlands
Posts: 427
| | | re: Passing char[][] as argument Quote:
Originally Posted by Banfa Actually in C the correct form avoiding unrequired casts is
char ** arr = malloc(num*(maxLen+1)); Casting still silently takes place here since malloc always returns void*. Writing (char**) makes it more explicit but is indeed not required; some compilers may warn that implicit casting is taking place if on a 'paranoid' warning level, although probably not when casting from void, come to think of it. Quote:
Originally Posted by Banfa assuming you want num*(maxLen+1) pointers although I would have thought that num pointers would be enough. Right, assuming krreks wants to store num strings, each of length maxLen+1, then he'll need num pointers to char[maxLen+1] arrays; -
char (*array)[num] = malloc(num*(maxLen+1)); // C
-
char (*array)[num] = new char[num][maxLen+1]; // C++
|  | AdministratorVoR | | Join Date: Feb 2006 Location: South West UK
Posts: 6,168
| | | re: Passing char[][] as argument Quote:
Originally Posted by arnaudk Casting still silently takes place here since malloc always returns void*. Writing (char**) makes it more explicit but is indeed not required; some compilers may warn that implicit casting is taking place if on a 'paranoid' warning level. True but I have see too many programmers silence implicit casting between types warnings with a cast when they had an actual error that needed fixing thus hiding the error.
The programmer should not put in casts by default, then if they get warnings they should be asking can I alter my code to remove with warning without a cast and only then if the answer is no should they put in a cast.
Explicit casting basically switches off all the compilers checks that things are being done correctly.
| | Needs Regular Fix | | Join Date: Sep 2007 Location: The Netherlands
Posts: 427
| | | re: Passing char[][] as argument
Ah, OK, I see your point.
| | Newbie | | Join Date: Oct 2008
Posts: 22
| | | re: Passing char[][] as argument
I ended up solving my problem with the following piece of code. - char * fillFileArr(char * buf, int num, int maxLen) {
-
char * arr = (char *)malloc(num*(maxLen+1));
-
-
int word=0, wordPos=0, bufferPos=0;
-
while(word<num && buf[bufferPos]!='\0') {
-
if(buf[bufferPos]=='\n') {
-
arr[(word*(maxLen+1))+wordPos] = '\0';
-
-
word++;
-
wordPos=0;
-
} else {
-
arr[(word*(maxLen+1))+wordPos++] = buf[bufferPos];
-
}
-
bufferPos++;
-
}
-
-
return arr;
-
}
-
-
void printFileArr(char * files, int num, int maxLen, int withIndex, int indexStart) {
-
int i, index=indexStart;
-
for(i=0; i<num; i++) {
-
if(withIndex==1)
-
printf("! [%2d] ", index++);
-
else
-
printf("! ");
-
printf("%s\n", files+((maxLen+1)*i));
-
}
-
}
-
-
char * getFromFileArr(char * arr, int maxLen, int wantedIndex) {
-
return (arr+((maxLen+1)*wantedIndex));
-
}
| | Moderator | | Join Date: Mar 2007 Location: North Bend Washington USA
Posts: 5,366
| | | re: Passing char[][] as argument
The correct code for allocating a 2D array is: -
char (* arr)[maxLen+8] = malloc(num*(maxLen+1));
-
Your function should have had a char (*)[maxLen+8] argument plus one argument for the number of maxLen+8 arrays.
Read this: http://bytes.com/forum/thread772412.html.
|  | | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,439 network members.
|