1

I'm trying to assign the names to clients in a TCP server, but the strcpy() function is giving me a segmentation fault.

struct clients{
  int client_fd;
  char* name;
  struct clients* next;
}

struct clients* first;
first->client_fd = 1;
first->name = NULL;
memset(&first->name, 0, sizeof(first->name));
first->name = (char*)malloc(100*sizeof(char));
strcpy(first->name, "User");
first->next = NULL;
ggorlen
  • 44,755
  • 7
  • 76
  • 106
NNNNNNN
  • 29
  • 1
  • 7

1 Answers1

5

The pointer struct clients* first; doesn't point to any mallocd memory, so trying to access a property on it like first->client_id = 1 is an uninitialized pointer dereference.

Because behavior is undefined after the dereference, the segmentation fault could occur at strcpy (or anywhere else, but strcpy is not the culprit). Consider using a tool like valgrind to identify these illegal memory accesses when they occur.

Also,

  • the lines:

      first->name = NULL;
      memset(&first->name, 0, sizeof(first->name));
    

    don't really do anything since the first->name memory location is subsequently written over. You may omit these.

  • (char*)malloc(100*sizeof(char)); can just be malloc(5). sizeof(char) is guaranteed to be 1 byte, (char *) is an unnecessary cast and 100 is too much memory for "User", which only needs 5 characters (one for the null terminator).

  • free allocated memory to avoid leaks.

  • Checking malloc's return value to ensure the memory was successfully allocated is a good idea.

  • You can use strdup instead of the malloc/strcpy pair but the drawback of this is that you might forget that strdup allocated memory that needs to be freed.

Here's a re-write (malloc return checks omitted):

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

struct clients {
    int client_fd;
    char* name;
    struct clients* next;
};

int main(void) {
    struct clients* first = malloc(sizeof(*first));
    first->client_fd = 1;
    first->name = malloc(5);
    strcpy(first->name, "User");
    first->next = NULL;

    printf("%d %s\n", first->client_fd, first->name); // => 1 User

    free(first->name);
    free(first);
    return 0;
}
ggorlen
  • 44,755
  • 7
  • 76
  • 106