Passing char[][] as argument

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • krreks
    New Member
    • Oct 2008
    • 22

    Passing char[][] as argument

    I'm trying to pass this array

    Code:
    char files[num][maxLen+8];
    like this

    Code:
    if(fillFileArr(&(files[0][0]), &(buf[0]), num)==-1)
    	return -1;
    to this function

    Code:
    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
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    &(files[0][0]) has type char *

    but

    int fillFileArr(cha r ** 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(cha r (*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.

    Comment

    • arnaudk
      Contributor
      • Sep 2007
      • 425

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

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #4
        It probably here:
        Code:
        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:
        Code:
        char files[num][maxLen+8];
        so the function argument has to be a pointer to an array of maxLen+8:
        Code:
        int fillFileArr(char (* files)[maxLen+8], char * buf, int num) { 
        etc...
        Read this: http://bytes.com/forum/thread772412.html.

        Comment

        • krreks
          New Member
          • Oct 2008
          • 22

          #5
          Originally posted by weaknessforcats
          It probably here:
          Code:
          if(fillFileArr(&(files[0][0]), &(buf[0]), num)==-1) 
              return -1;
          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:
          Code:
          char files[num][maxLen+8];
          so the function argument has to be a pointer to an array of maxLen+8:
          Code:
          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 :)

          Comment

          • krreks
            New Member
            • Oct 2008
            • 22

            #6
            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 **.

            Code:
            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

            Code:
            arr[y][x];
            on this data - right?

            Yours sincerely

            Comment

            • arnaudk
              Contributor
              • Sep 2007
              • 425

              #7
              Check your types: is (char *) malloc(num) of type char** on line 2? Did you try to compile this code?

              Comment

              • krreks
                New Member
                • Oct 2008
                • 22

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

                Comment

                • donbock
                  Recognized Expert Top Contributor
                  • Mar 2008
                  • 2427

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

                  Comment

                  • arnaudk
                    Contributor
                    • Sep 2007
                    • 425

                    #10
                    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*(max Len+1)); now you have an array big enough to hold num strings of maxLen characters (plus '\0'), and drop the malloc() on line 6.

                    Comment

                    • krreks
                      New Member
                      • Oct 2008
                      • 22

                      #11
                      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

                      Code:
                      gcc -o server server.c helpers.o protocol.o -I. -DDEBUG -g -Wall

                      Comment

                      • Banfa
                        Recognized Expert Expert
                        • Feb 2006
                        • 9067

                        #12
                        Originally posted by arnaudk
                        The correct form should be
                        char ** arr = (char **) malloc(num*(max Len+1));
                        Actually in C the correct form avoiding unrequired casts is

                        char ** arr = malloc(num*(max Len+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.

                        Comment

                        • arnaudk
                          Contributor
                          • Sep 2007
                          • 425

                          #13
                          Originally posted by Banfa
                          Actually in C the correct form avoiding unrequired casts is
                          char ** arr = malloc(num*(max Len+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.
                          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;
                          Code:
                          char (*array)[num] = malloc(num*(maxLen+1)); // C
                          char (*array)[num] = new char[num][maxLen+1]; // C++

                          Comment

                          • Banfa
                            Recognized Expert Expert
                            • Feb 2006
                            • 9067

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

                            Comment

                            • arnaudk
                              Contributor
                              • Sep 2007
                              • 425

                              #15
                              Ah, OK, I see your point.

                              Comment

                              Working...