Thread: array of pointers passed as argument to fgets

  1. #1
    Registered User shruthi's Avatar
    Join Date
    Jan 2012
    Posts
    59

    array of pointers passed as argument to fgets

    Hi Everyone!
    I am trying to use array of pointers to store strings and trying to take the input from the user for that I am using fgets,but it's throwing a segmentation fault.what is the right syntax when dealing with array of pointer with fgets?
    Program :
    Trying to store 3 strings:name,email id and subject,for this I am using char array of pointers.
    Code:
    #include<stdio.h>
    int main()
    {
        char *info[3];
        fputs("enter name:",stdout);
        fgets(info[0],sizeof(info),stdin);  // this line is throwing segmentation fault
        fputs(info,stdout); 
        return 0;
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Well you need to allocate space for the strings.

    1.
    info[0] = malloc( 100 );
    fgets(info[0],100,stdin);


    2.
    char info[3][100];
    fgets(info[0],sizeof(info[0]),stdin);
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User shruthi's Avatar
    Join Date
    Jan 2012
    Posts
    59
    Quote Originally Posted by Salem View Post
    Well you need to allocate space for the strings.

    1.
    info[0] = malloc( 100 );
    fgets(info[0],100,stdin);


    2.
    char info[3][100];
    fgets(info[0],sizeof(info[0]),stdin);
    Code:
    #include<stdio.h>
    int main()
    {
        char *days[2]={"mon","tue"};
        printf("%s\n",days[0]);
         return 0;
    }
    Where in data mon & tue getting stored?
    Instead of initialising in the program I want give input from the keyboard.

  4. #4
    Registered User shruthi's Avatar
    Join Date
    Jan 2012
    Posts
    59
    I am tryin to use char array of pointer instead of a 2d char array,to reduce the fixed size usage of the 2d array.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > Where in data mon & tue getting stored?
    Well the compiler basically generates
    Code:
    static const char anon1[] = "mon";
    static const char anon2[] = "tue";
    char *days[2]={anon1,anon2};

    > Instead of initialising in the program I want give input from the keyboard.
    Which is fair enough, but you must provide your own memory allocation.
    Just declaring an array of pointers doesn't magic into existence memory you can use.

    Normally, I would
    - fgets() to a fixed buffer
    - malloc the appropriate sized block
    - strcpy the buffer to the block
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by shruthi View Post
    I am tryin to use char array of pointer instead of a 2d char array,to reduce the fixed size usage of the 2d array.
    If each word has three letters, there would be no space saving, since either type of array entry, would need 3 letters + 1 end of string char, for each word in the array.

    For example:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void) {
       char *day[7];
       int i;
       for(i=0;i<7;i++) {
          day[i]=malloc(4);
          printf("Enter a three letter day abbreviation: ");
          
          fgets(day[i], 4,stdin);
          getchar();
          printf("%d. day: %s\n",i+1,day[i]);
       }
       for(i=0;i<7;i++)
          printf("%d) day: %s\n",i+1,day[i]);
       printf("\n");
       return 0;
    }
    To save space, you'd want to put the user's entry into a second array, and then measure it's length (and probably remove the \n which fgets() adds to the string).

    Once you have the length of the entry, you could use that variable in malloc(), instead of a constant like here (the 4). Then copy the string into the final position in the array of pointers to strings.

    Give that a try.

  7. #7
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Adak - You forgot to free the memory you allocated.

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by Click_here View Post
    Adak - You forgot to free the memory you allocated.
    Two reasons:

    #1) I don't believe this is the type of program that he wants, since there is no space being saved, which is what he wants to do.
    This is "some" code, based on his example, but not "the answer" to his question. I intended that the OP would post back, asking "OK, how can I do this then, so I can save space?"

    #2) I'm running in a virtual environment. All memory is freed, anyway. For small programs that I will probably never run again, I don't always bother with it, anymore. Good on ya, if you still free all the pointers, for every little snippet of code.

  9. #9
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Adak:
    "For small programs that I will probably never run again, I don't always bother with it"
    I didn't know we could do that

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Click_here
    I didn't know we could do that
    Err... it has always been your choice whether you want to free memory or not. Adak is just saying that since the memory allocated to the process will be returned to the OS when the process is terminated, he chooses not to bother with doing things correctly in a pedantic fashion for a small throwaway program. Pragmatic, yes, but then if this develops into a bad habit...
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    So just to clarify - You do not need to free memory that you allocate using malloc, because it will automatically be returned when the process is terminated.

    I thought that it was a memory leak if you didn't free the allocated memory - I'm always happy to learn something new

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Click_here
    So just to clarify - You do not need to free memory that you allocate using malloc, because it will automatically be returned when the process is terminated.
    No, you need to free memory that you allocate using malloc, because it might not be automatically be made available when the process is terminated, or you might be dealing with a long lived process, etc.

    Quote Originally Posted by Click_here
    I thought that it was a memory leak if you didn't free the allocated memory
    It is a memory leak. Adak can get away with it here because under the particular circumstances, the memory leak does not matter since the memory will be made available to other processes very shortly thereafter. Hence, it effectively is not a memory leak, thanks to a smart OS (or possibly in Adak's case, thanks to the virtual machine's controller).

    Put it in this way: Adak's example program really should have been just an incomplete code snippet. Your pointing out that Adak did not free the memory allocated is a legitimate observation. Adak's explanation is really just an excuse.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  13. #13
    Registered User shruthi's Avatar
    Join Date
    Jan 2012
    Posts
    59
    Quote Originally Posted by Adak View Post
    If each word has three letters, there would be no space saving, since either type of array entry, would need 3 letters + 1 end of string char, for each word in the array.

    For example:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void) {
       char *day[7];
       int i;
       for(i=0;i<7;i++) {
          day[i]=malloc(4);
          printf("Enter a three letter day abbreviation: ");
          
          fgets(day[i], 4,stdin);
          getchar();
          printf("%d. day: %s\n",i+1,day[i]);
       }
       for(i=0;i<7;i++)
          printf("%d) day: %s\n",i+1,day[i]);
       printf("\n");
       return 0;
    }
    To save space, you'd want to put the user's entry into a second array, and then measure it's length (and probably remove the \n which fgets() adds to the string).

    Once you have the length of the entry, you could use that variable in malloc(), instead of a constant like here (the 4). Then copy the string into the final position in the array of pointers to strings.

    Give that a try.
    I guess it's just easier to use a 2d char array.
    I thought since you can store strings
    Code:
    char *arr[3]={"mon","tuesday","wednesday"};
    I thought one could possibly take the user input and it would get automatically stored the same way how I have show it above.
    I was just trying to use that advantage of array of pointers to 2d char array.But what I have understood is you still have to create memory,I think I'll just use 2d char array instead of calculating the length and again putting it in to the array.

  14. #14
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    @Click_here: For a program of any importance, yes, you should free the memory you allocate.

    @shruthi: You CAN save memory by using 2D (pointer to pointer) arrays, just like you were thinking about. It's just not "automatic", like the pre-defined strings you show: "mon", "tuesday", "wednesday". Each string needs to have it's length known, and the memory allocated for it. This would be a better program, (and a useful example), so it would be VERY worthwhile to free any allocated memory.


    If you are ready to study and or practice using char pointers, it's a very worthwhile skill to learn how it works.
    Last edited by Adak; 09-06-2012 at 06:38 AM.

  15. #15
    Registered User shruthi's Avatar
    Join Date
    Jan 2012
    Posts
    59
    Quote Originally Posted by Adak View Post
    @Click_here: For a program of any importance, yes, you should free the memory you allocate.

    @shruthi: You CAN save memory by using 2D (pointer to pointer) arrays, just like you were thinking about. It's just not "automatic", like the pre-defined strings you show: "mon", "tuesday", "wednesday". Each string needs to have it's length known, and the memory allocated for it. This would be a better program, (and a useful example), so it would be VERY worthwhile to free any allocated memory.


    If you are ready to study and or practice using char pointers, it's a very worthwhile skill to learn how it works.
    Ok,Ive given it a try.
    Code:
     #include#include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
     int main()
    {
    char *str1[3];
    char data[40];
    int len;
    fgets(data,sizeof(data),stdin);
    fputs(data,stdout);
    len=strlen(data);printf("length of the string=%d\n",len);
    str1[0]=malloc(strlen(data));
    strncpy(str1[0],data,len);printf("%s\n",str1[0]);
    free(str1[0]);
    return 0;
    }
    

    Able to take the input,find out it's length,create a memory of that size & copy the data into that,but the only thing is not able to place the null character after copying.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. data type of passed argument
    By fran1942 in forum C Programming
    Replies: 1
    Last Post: 01-08-2011, 12:05 AM
  2. Replies: 3
    Last Post: 04-10-2009, 12:57 AM
  3. Replies: 1
    Last Post: 10-21-2007, 07:44 AM
  4. how to check if a argument passed is integer
    By powinda in forum C Programming
    Replies: 7
    Last Post: 03-07-2004, 05:26 PM
  5. could enum be passed as argument ?
    By black in forum C++ Programming
    Replies: 4
    Last Post: 06-27-2002, 11:49 PM