473,326 Members | 2,110 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

Passing char[][] as argument

22
I'm trying to pass this array

Expand|Select|Wrap|Line Numbers
  1. char files[num][maxLen+8];
like this

Expand|Select|Wrap|Line Numbers
  1. if(fillFileArr(&(files[0][0]), &(buf[0]), num)==-1)
  2.     return -1;
to this function

Expand|Select|Wrap|Line Numbers
  1. int fillFileArr(char ** files, char * buf, int num) {
  2.     int word=0, wordPos=0, bufferPos=0;
  3.     while(word<num && buf[bufferPos]!='\0') {
  4.         if(word==0 && wordPos==0 && bufferPos==0)
  5.             printf("! ");
  6.         if(buf[bufferPos]=='\n') {
  7.             if(buf[bufferPos+1]!='\0')
  8.                 printf("\n! ");
  9.  
  10.  
  11.             word++;
  12.             wordPos=0;
  13.         } else {
  14.             printf("files[%d][%d] = %c\n", word, wordPos, buf[bufferPos]);
  15.             files[word][wordPos++] = buf[bufferPos];
  16.             printf("%c",buf[bufferPos]);
  17.         }
  18.         bufferPos++;
  19.     }
  20.     return 0;
  21. }
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
Nov 17 '08 #1
16 2507
Banfa
9,065 Expert Mod 8TB
&(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.
Nov 17 '08 #2
arnaudk
424 256MB
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.
Nov 17 '08 #3
weaknessforcats
9,208 Expert Mod 8TB
It probably here:
Expand|Select|Wrap|Line Numbers
  1. if(fillFileArr(&(files[0][0]), &(buf[0]), num)==-1) 
  2.     return -1; 
  3.  
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:
Expand|Select|Wrap|Line Numbers
  1. char files[num][maxLen+8]; 
  2.  
so the function argument has to be a pointer to an array of maxLen+8:
Expand|Select|Wrap|Line Numbers
  1. int fillFileArr(char (* files)[maxLen+8], char * buf, int num) { 
  2. etc...
  3.  
Read this: http://bytes.com/forum/thread772412.html.
Nov 17 '08 #4
krreks
22
It probably here:
Expand|Select|Wrap|Line Numbers
  1. if(fillFileArr(&(files[0][0]), &(buf[0]), num)==-1) 
  2.     return -1; 
  3.  
Your function needs a char** and you have provided a char*.
Ok

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

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:
Expand|Select|Wrap|Line Numbers
  1. char files[num][maxLen+8]; 
  2.  
so the function argument has to be a pointer to an array of maxLen+8:
Expand|Select|Wrap|Line Numbers
  1. int fillFileArr(char (* files)[maxLen+8], char * buf, int num) { 
  2. etc...
  3.  
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 :)
Nov 17 '08 #5
krreks
22
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 **.

Expand|Select|Wrap|Line Numbers
  1. char ** fillFileArr(char * buf, int num, int maxLen) {
  2.     char ** arr = (char *) malloc(num);
  3.     int y;
  4.  
  5.     for(y=0; y<num; y++) {
  6.         arr[y] = (char *) malloc(maxLen+1);
  7.     }
  8.  
  9.     int word=0, wordPos=0, bufferPos=0;
  10.     while(word<num && buf[bufferPos]!='\0') {
  11.         if(word==0 && wordPos==0 && bufferPos==0)
  12.             printf("! ");
  13.         if(buf[bufferPos]=='\n') {
  14.             arr[word][wordPos] = '\0';
  15.  
  16.             if(buf[bufferPos+1]!='\0')
  17.                 printf("\n! ");
  18.  
  19.             word++;
  20.             wordPos=0;
  21.         } else {
  22.             arr[word][wordPos++] = buf[bufferPos];
  23.             printf("%c", buf[bufferPos]);
  24.         }
  25.         bufferPos++;
  26.     }
  27.  
  28.     return arr;
  29. }
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

Expand|Select|Wrap|Line Numbers
  1. arr[y][x];
on this data - right?

Yours sincerely
Nov 19 '08 #6
arnaudk
424 256MB
Check your types: is (char *) malloc(num) of type char** on line 2? Did you try to compile this code?
Nov 19 '08 #7
krreks
22
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...
Nov 19 '08 #8
donbock
2,426 Expert 2GB
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.
Nov 19 '08 #9
arnaudk
424 256MB
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.
Nov 19 '08 #10
krreks
22
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

Expand|Select|Wrap|Line Numbers
  1. gcc -o server server.c helpers.o protocol.o -I. -DDEBUG -g -Wall
Nov 19 '08 #11
Banfa
9,065 Expert Mod 8TB
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.
Nov 19 '08 #12
arnaudk
424 256MB
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.
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;
Expand|Select|Wrap|Line Numbers
  1. char (*array)[num] = malloc(num*(maxLen+1)); // C
  2. char (*array)[num] = new char[num][maxLen+1]; // C++
Nov 19 '08 #13
Banfa
9,065 Expert Mod 8TB
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.
Nov 19 '08 #14
arnaudk
424 256MB
Ah, OK, I see your point.
Nov 19 '08 #15
krreks
22
I ended up solving my problem with the following piece of code.

Expand|Select|Wrap|Line Numbers
  1. char * fillFileArr(char * buf, int num, int maxLen) {
  2.     char * arr = (char *)malloc(num*(maxLen+1));
  3.  
  4.     int word=0, wordPos=0, bufferPos=0;
  5.     while(word<num && buf[bufferPos]!='\0') {
  6.         if(buf[bufferPos]=='\n') {
  7.             arr[(word*(maxLen+1))+wordPos] = '\0';
  8.  
  9.             word++;
  10.             wordPos=0;
  11.         } else {
  12.             arr[(word*(maxLen+1))+wordPos++] = buf[bufferPos];
  13.         }
  14.         bufferPos++;
  15.     }
  16.  
  17.     return arr;
  18. }
  19.  
  20. void printFileArr(char * files, int num, int maxLen, int withIndex, int indexStart) {
  21.     int i, index=indexStart;
  22.     for(i=0; i<num; i++) {
  23.         if(withIndex==1)
  24.             printf("! [%2d] ", index++);
  25.         else
  26.             printf("! ");
  27.         printf("%s\n", files+((maxLen+1)*i));
  28.     }
  29. }
  30.  
  31. char * getFromFileArr(char * arr, int maxLen, int wantedIndex) {
  32.     return (arr+((maxLen+1)*wantedIndex));
  33. }
Nov 19 '08 #16
weaknessforcats
9,208 Expert Mod 8TB
The correct code for allocating a 2D array is:

Expand|Select|Wrap|Line Numbers
  1. char (* arr)[maxLen+8] = malloc(num*(maxLen+1)); 
  2.  
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.
Nov 19 '08 #17

Sign in to post your reply or Sign up for a free account.

Similar topics

8
by: Alex Vinokur | last post by:
Various forms of argument passing ================================= C/C++ Performance Tests ======================= Using C/C++ Program Perfometer...
58
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...
17
by: BlindHorse | last post by:
Help!!! I need someone to tell me why I am getting the err msg error C2440: '=' : cannot convert from 'char *' to 'char' //==================== #include <iostream>
1
by: Foxy Kav | last post by:
Hi everyone, im a first year UNI student doing a programming subject and im stuck on how to get rid of my global variables, char stringarray and char emptystring. I was wondering if anyone could...
3
by: Goh, Yong Kwang | last post by:
I'm trying to create a function that given a string, tokenize it and put into a dynamically-sized array of char* which is in turn also dynamically allocated based on the string token length. I...
10
by: Pete | last post by:
Can someone please help, I'm trying to pass an array to a function, do some operation on that array, then return it for further use. The errors I am getting for the following code are, differences...
15
by: Carramba | last post by:
hi! I am trying to confirm if input is digit, so I thought it would by easy to do it with with isdigit() funktion, but how do I pass arrays to it if the imput is more then 1 sign? #include...
9
by: Juggernaut | last post by:
I am trying to create a p_thread pthread_create(&threads, &attr, Teste, (void *)var); where var is a char variable. But this doesnt't work, I get this message: test.c:58: warning: cast to pointer...
3
by: Amit_Basnak | last post by:
Dear friends I have to pass the objec of a class which is a part of afunction in thefunction call. my code looks like this now #include <iostream.h> #include <waspc/common.h> #include...
6
by: Andy Baker | last post by:
I am attempting to write a .NET wrapper for a C++ DLL file, but am having problems with passing strings as parameters. How should I be writing my C# function call when the C header file is...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you

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.