Thread: Small array of strings prob

  1. #1
    Registered User
    Join Date
    Aug 2005
    Posts
    4

    Small array of strings prob

    Ok, here's what I got

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    /* Function Prototypes */
    void getClassData(int *);
    void getStudentData(char *n[], int s[], int class);
    
    
    int main(void)
    {
            /* Variables declared */
            int i, class1;
    
            getClassData(&class1);
    
            char *n1[class1];
            int s1[class1];
    
            getStudentData(n1, s1, class1);
    
            printf("-Class 1-\n");
    
            for(i = 0; i < class1; i++)
            {
                    printf("n1[%d] %s s1[%d] %d\n", i, n1[i], i, s1[i]);
            }
    }
    
    void getClassData(int *class1)
    {
            printf("Number of students in class 1? ");
            scanf("%d", &*class1);
    }
    
    void getStudentData(char *n[], int s[], int class)
    {
            char name[10];
            int j, score;
    
            for(j = 0; j < class; j++)
            {
                    printf("Enter student's name and score? ");
                    scanf("%s %d", &name, &score);
    
                    n[j] = name;
                    s[j] = score;
            }
    }
    Now, I just wanted to check to see if the array was getting filled correctly and this is what the output looks like

    Number of students in class 1? 3
    Enter student's name and score? Ben 100
    Enter student's name and score? Bill 95
    Enter student's name and score? Bob 90
    -Class 1-
    n1[0] Bob s1[0] 100
    n1[1] Bob s1[1] 95
    n1[2] Bob s1[2] 90

    Quite obvious the problem, should be three different names. Any ideas?

    Thanks,
    -B
    Last edited by bstringer; 08-03-2005 at 08:56 AM.

  2. #2
    vae victus! skorman00's Avatar
    Join Date
    Nov 2003
    Posts
    594
    a few things that are going wrong here:

    You're declaring arrays with variable size. That can't happen, and I'm not sure why you're compiler isn't whining about it. You either have to set them to a constant size, or dynamically create them (malloc() / calloc())

    In your getStudentData function, all of those strings are being set to name[], which is always reset. So the only name you get is the last one you fill it with. And that's only working because your debugger is nice. After that function, name[] no longer exists, and the elements in n1[] are accessing memory that they shouldn't.

  3. #3
    Registered User cbastard's Avatar
    Join Date
    Jul 2005
    Location
    India
    Posts
    167
    i dont know how ur code is even compiling.the u cant create array with dynamic size.if thats not a problem for ur compiler then.

    Code:
        char name[10];
            int j, score;
    
            for(j = 0; j < class; j++)
            {
                    printf("Enter student's name and score? ");
                    scanf("%s %d", &name, &score);
    
                    n[j] = name;
                    s[j] = score;
            }
    all the array of pointers points to the same block of memory which is pointed by name.so all gives same result.u can use

    Code:
        char name[10];
            int j, score;
    
            for(j = 0; j < class; j++)
            {
                    printf("Enter student's name and score? ");
                    scanf("%s %d", &name, &score);
    
                    strcpy(n[j],name);
                    s[j] = score;
            }
    use malloc to allocate memory not calloc

  4. #4
    Registered User cbastard's Avatar
    Join Date
    Jul 2005
    Location
    India
    Posts
    167
    Quote Originally Posted by skorman00
    In your getStudentData function, all of those strings are being set to name[], which is always reset. So the only name you get is the last one you fill it with. And that's only working because your debugger is nice. After that function, name[] no longer exists, and the elements in n1[] are accessing memory that they shouldn't.
    After the function call only the array variable will be destroyed not the memory contents.if something can point to that peice of memory it can access the contents.so no point of good debugger

  5. #5
    Registered User
    Join Date
    Aug 2005
    Posts
    4
    You're declaring arrays with variable size
    Im not sure what you mean by this. I dont see anywhere that I am varying the array size. The array is declared after the user decides how many students, then it stays that size.

    strcpy(n[j],name);
    I tried that, and it gave me "Segmentation fault".

  6. #6
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Quote Originally Posted by cbastard
    After the function call only the array variable will be destroyed not the memory contents.if something can point to that peice of memory it can access the contents.so no point of good debugger
    Incorrect. The entire name array is stored on the local stack. Once the function returns the memory name is stored in is "freed" and use of that memory becomes undefined. If it was declared as char *name; and then it pointed to memory that wasn't on the local stack, then it wouldn't be a problem. But in this case, the contents of name are stored on the local stack, so using that memory after the function returns is a Bad Thing.
    If you understand what you're doing, you're not learning anything.

  7. #7
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Quote Originally Posted by bstringer
    I tried that, and it gave me "Segmentation fault".
    You need to allocate memory for n[j] first.
    If you understand what you're doing, you're not learning anything.

  8. #8
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    /* Function Prototypes */
    void getClassData(int *);
    void getStudentData(char *n[], int s[], int class);
    
    int main(void)
    {
      /* Variables declared */
      int i, class1;
      char **n1;
      int *s1;
    
      getClassData(&class1);
    
      n1 = malloc(sizeof(char *) * class1);
      s1 = malloc(sizeof(int) * class1);
    
      // Always make sure allocations succeed
      if(!n1 || !s1)
      {
        fprintf(stderr, "Memory allocation failure.\n");
        return 1;
      }
    
      getStudentData(n1, s1, class1);
    
      printf("-Class 1-\n");
    
      for(i = 0; i < class1; i++)
      {
        printf("n1[%d] %s s1[%d] %d\n", i, n1[i], i, s1[i]);
        free(n1[i]);
      }
    
      // Always free allocated memory
      free(n1);
      free(s1);
    
      return 0;
    }
    
    void getClassData(int *class1)
    {
      printf("Number of students in class 1? ");
      scanf("%d", class1);  // class1 is already a pointer. No need for &*
    }
    
    void getStudentData(char *n[], int s[], int class)
    {
      char name[10];
      int j, score;
    
      for(j = 0; j < class; j++)
      {
        printf("Enter student's name and score? ");
        scanf("%s %d", name, &score);
    
        n[j] = malloc(strlen(name) + 1);
        strcpy(n[j], name);
        s[j] = score;
      }
    }
    If you understand what you're doing, you're not learning anything.

  9. #9
    Registered User
    Join Date
    Aug 2005
    Posts
    4
    My apologies skorman00. I just didnt see what part you were talking about when you said I didnt have memory allocated.

    Thanks itsme86! I looked up some malloc stuff on the forums here and got a head start on you, but thanks. Only thing I didnt understand with your cose was:

    Code:
    n[j] = malloc(strlen(name) + 1);
    If you wouldnt mind explaining that one to me, I would appreciate it.

    Appreciate all the input guys. With this example, I was able to implement it into my whole program which includes 4 classes with variable numbers of students and scores. Next I get to do highest grades in each class and averages which should be easy enough .

  10. #10
    Registered User cbastard's Avatar
    Join Date
    Jul 2005
    Location
    India
    Posts
    167
    Quote Originally Posted by bstringer



    I tried that, and it gave me "Segmentation fault".
    i told u to allocate memory using malloc.

  11. #11
    Registered User cbastard's Avatar
    Join Date
    Jul 2005
    Location
    India
    Posts
    167
    Code:
    n[j] = malloc(strlen(name) + 1);
    strlen is a function to give length of string --name.malloc is used to allocate enough memory to hold name and 1 for null character.
    thats according to my knowledge.is it correct itsme86.thanks for ur reply last time.i will further do some R&D on it to know more

  12. #12
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    If you wouldnt mind explaining that one to me, I would appreciate it.
    Absolutely!

    n is an array of strings. The first thing I did (in the main() function) was allocate memory for the array depending on how many students there were. You need enough memory to store a pointer to a string for each student.

    The second allocation for n (the one you asked about) allocates memory for the strings themselves. You need to allocate enough memory for the characters of the name plus the terminating '\0' that actually makes it a string. So with the name "Bob" you need 4 bytes ('B', 'o', 'b', '\0'). strlen(name) returns 3 (it doesn't count the terminating '\0') so you just add 1 to the return value of strlen().
    If you understand what you're doing, you're not learning anything.

  13. #13
    Registered User
    Join Date
    Aug 2005
    Posts
    4
    Ah, forgot about the term char. Got it now. Thanks again both of you.

    -B

  14. #14
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by cbastard
    Code:
        char name[10];
            int j, score;
    
            for(j = 0; j < class; j++)
            {
                    printf("Enter student's name and score? ");
                    scanf("%s %d", &name, &score);
    
                    n[j] = name;
                    s[j] = score;
            }
    all the array of pointers points to the same block of memory which is pointed by name.so all gives same result.u can use

    Code:
        char name[10];
            int j, score;
    
            for(j = 0; j < class; j++)
            {
                    printf("Enter student's name and score? ");
                    scanf("%s %d", &name, &score);
    
                    strcpy(n[j],name);
                    s[j] = score;
            }
    use malloc to allocate memory not calloc
    Lose the &.


    Quzah.
    Hope is the first step on the road to disappointment.

  15. #15
    Registered User cbastard's Avatar
    Join Date
    Jul 2005
    Location
    India
    Posts
    167
    oh sorry that was a typo. i just pasted his whole code and added strcpy func.i did'nt see this thing

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 03-19-2009, 10:56 AM
  2. Swapping strings in an array of strings
    By dannyzimbabwe in forum C Programming
    Replies: 3
    Last Post: 03-03-2009, 12:28 PM
  3. array of strings
    By jordanguyoflove in forum C Programming
    Replies: 9
    Last Post: 11-19-2008, 10:04 AM
  4. Build an array of strings dynamically
    By Nazgulled in forum C Programming
    Replies: 29
    Last Post: 04-07-2007, 09:35 PM
  5. How do u write up an array of strings?
    By hot_ice in forum C Programming
    Replies: 1
    Last Post: 11-19-2001, 08:41 PM