0

I need to write a program that will recieve (from the user) the number of players in a basketball team and then I need to create an array in a dynamic way. The program will sort the array in an alphabetic order and then print it like that aswell. I wrote this code:

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>

#define LENGTH 20

int main(void)
{
    int numplayers, i, j;
    char persname[LENGTH], tname[LENGTH], temp[LENGTH];

    printf("Please insert the amount of basketball players in the group\n");
    scanf("%d", &numplayers);

    char **players = (char **) malloc(numplayers * sizeof(char *));

    printf("Please insert the names of your %d basketball players\n", numplayers);
    for (i = 0; i < numplayers; i++) {
        gets(persname);
        strcpy(persname[i], tname[i]);
    }

    for (i = 0; i < numplayers-1; i++) {
        for (j = i+1; j < numplayers; j++) {
            if (strcmp(persname[i], persname[j])) {
                strcpy(temp[i], persname[i]);
                strcpy(persname[i], persname[j]);
                strcpy(persname[j], temp);
            }
        }
    }

    for (i = 0; i < numplayers; i++) {
        printf("%s\t\t%s\n", tname[i], persname[i]);
    }

    return 0;
}

But when I run the code, I get an error right after typing the amount of players in the team, Unhandled exception at 0x507340E3 (msvcr120d.dll) in Question4.exe: 0xC0000005: Access violation reading location 0xFFFFFFCC. What did I do wrong.

Sean Bright
  • 118,630
  • 17
  • 138
  • 146
Amnon Hanuhov
  • 21
  • 1
  • 3
  • 9

2 Answers2

2

Your loop that inputs all the names doesn't use players. Instead it uses pername and tname, incorrectly. This line:

strcpy(persname[i], tname[i]);

shouldn't compile, you're mixing up types in a way that just doesn't make any sense. You should input a line, then dynamically allocate new memory into players[i] and copy the input there. If you have strdup(), that's what it's good for.

Basically the input loop should be something like:

for (i = 0; i < numplayers; i++)
{
    char line[1024];
    if(fgets(line, sizeof line, stdin) != NULL)
    {
       const size_t len = strlen(line);
       players[i] = malloc(len + 1);
       if(players[i] == NULL)
       {
         fprintf(stderr, "**Out of memory!\n");
         exit(1);
       }
       memcpy(players[i], line, len + 1);
    }
    else
      fprintf(stderr, "**I/O error!\n");
}

This uses fgets() which is way safer than the horribly never-to-be-used gets() monster.

Also, you're not allocating any room for the individual names, just for the array of string pointers.

This line:

char** players = (char**)malloc(numplayers*sizeof(char*));

can be simplified to the much clearer:

char** players = malloc(numplayers * sizeof *players);

No need to repeat type names, and no need to cast the return value of malloc().

Community
  • 1
  • 1
unwind
  • 391,730
  • 64
  • 469
  • 606
  • I am sorry but I did not understand, can you please write the line you mentioned for me? I did not study strdup() yet so I think I am not allowed to use that, I wrote the malloc line this way because that's how we were tought. – Amnon Hanuhov Apr 17 '15 at 12:54
0

I managed to solve it! :)

Here is my updated code:

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#define LENGTH 20
#define LENGTH2 20
int main(void)
{
    int numplayers, i, j;
    char persname[LENGTH][LENGTH2], temp[LENGTH];
    printf("Please insert the amount of basketball players in the group\n");
    scanf("%d", &numplayers);
    char** players = (char**)malloc(numplayers*sizeof(char));
    printf("Please insert the names of your %d basketball players\n", numplayers);
    for (i = 0; i < numplayers+1; i++)
    {
        gets(persname[i]);
    }
    for (i = 1; i < numplayers+1; i++)
    {
        for (j = 1; j < numplayers+1; j++)
        {
            if (strcmp(persname[j - 1], persname[j]) > 0)
            {
                strcpy(temp, persname[j - 1]);
                strcpy(persname[j - 1], persname[j]);
                strcpy(persname[j], temp);
            }
        }
    }
    printf("\nBasketball players names in order are : ");
    for (i = 0; i < numplayers+1; i++)
    {
        puts(persname[i]);
    }
    getch();
    free(players);
    system("PAUSE");
    return 0;
}
Amnon Hanuhov
  • 21
  • 1
  • 3
  • 9