-1

I'm trying to copy a string into a struct, but it doesn't display anything. Can you help me figure it out where the problem is?

typedef struct{
    long tipo;
    char *buffer;
}msg;

msg mess;

strcpy(mess.buffer,"hello");
printf("%s\n",mess.buffer);
Bodo
  • 9,287
  • 1
  • 13
  • 29
Marià
  • 255
  • 2
  • 12
  • 3
    `char *buffer` is a pointer, that has no memory allocated. Try `mess.buffer = "hello";` (text is not modifiable) or `mess.buffer = strdup("hello");` – Weather Vane Mar 09 '21 at 17:35
  • Note that `strdup` is non-standard (before C23 standard). If it is not available you can use `strlen`, `malloc` and `strcpy`. In both cases you should use `free` when you no longer need the memory allocated for the string. – Bodo Mar 09 '21 at 17:39
  • @Bodo I agree but I think memcpy would go faster than strcpy because you do not need to check for `'\0'`, you already got it thanks to `strlen`. I think OP is looking for a char array, the way is he is using its struct. – Antonin GAVREL Mar 09 '21 at 17:49
  • Note that the struct is irrelevant. You must first understand the problem with: `char *buffer; strcpy(buffer, "hello");` – William Pursell Mar 09 '21 at 18:42

2 Answers2

1

Observing the strcpy declaration

char * strcpy ( char * destination, const char * source );

We notice that it copies the chars from source and store them in destination. But note that it's not specified the length of destination. So it may cause problems if the destination is:

  • Smaller than the source (Overflow)
  • Not allocated to some space in the memory (Segmentation Fault)

It's because strcpy function tries to copy char by char until it gets to the end of the 'string'. See how it should look like:

char *strcpy(char *destination , const char *source ){
   char *saved = destination;
   while (*source){ // while is not NULL
       *destination++ = *source++;      // Pointer operation 
   }
   *destination = 0; // last position is set to 0 (which is NULL, end of string)
   return saved;
}

So when you perform strcpy(mess.buffer,"hello") you can't actually find mess.buffer++ because there's no next memory block since you did not allocated sequential memory. Thus, Segmentation Fault happens.

Finally, you could do:

/* Note that "hello" occupies 6 char spaces: 'h', 'e', 'l', 'l', 'o', '\0' */
int mySize = 10; 
mess.buffer = malloc(mySize * sizeof(char));
strcpy(mess.buffer, "hello") // 10 > 6 so OK
testing_22
  • 2,340
  • 1
  • 12
  • 28
0

Either assign the string directly (note that you will no long be able to modify this string):

msg mess = {.buffer= "hello"};

or use malloc and memcpy function from libc which will perform a memory allocation and copy the bytes of your string to your char pointer for you:

if (!(mess.buffptr = malloc(sizeof(char) * (strlen(s) + 1))))
    return 1;
memcpy(mess.buffptr, s, strlen(s));

But I think that what you are looking for is rather to use char buffer[128] instead of a char pointer, see the following example:

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

typedef struct{
  long tipo;
  char buffer[128];
  char *buffptr; // remove if not needed
} msg;

int main(){
  char *s = "hello";
  msg mess = {.buffer= "hello"};
  mess.buffer[1] = 'a';
  printf("'%s' assigned at struct initialization\n",mess.buffer);
  (void)mess.buffer;
  strcpy(mess.buffer,"hello");
  printf("'%s' char array strcpy\n",mess.buffer);
  int len = strlen(s) + 1; // to account for '\0'
  if (!(mess.buffptr = malloc(sizeof(char) * len)))
    return 1;
  if (len <= sizeof(mess.buffer))
    memcpy(mess.buffptr, s, len);
  printf("'%s' char ptr malloced\n",mess.buffptr);

  return 0;
}

You can read more about the different between a char pointer and a char array here

Antonin GAVREL
  • 9,682
  • 8
  • 54
  • 81
  • When you use `memcpy` to copy the string you have to use `strlen(s) + 1` to copy the `'\0'`. I suggest to store the length in a variable and use it both for `malloc` and `strcpy`. – Bodo Mar 09 '21 at 18:10
  • 1
    I must admit that I didn't check the big thirtd code block until now. The same error is still present in the second code block. Instead of `if(len <= 128)` I suggest `if(len <= sizeof(mess.buffer))`. Or maybe use `strncpy` in this case. – Bodo Mar 09 '21 at 18:32