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

int main(int argc, char *argv[]) {
    char string[] = "october"; // 7 letters

    strcpy(string, "september"); // 9 letters

    printf("the size of %s is %d and the length is %d\n\n", string,
        sizeof(string), strlen(string));

    return 0;
}

Output:

$ ./a.out
the size of september is 8 and the length is 9

Is there something wrong with my syntax or what?

pevik
  • 4,523
  • 3
  • 33
  • 44
beparas
  • 1,927
  • 7
  • 24
  • 30
  • 11
    You are writing past the end of the array `string`. This is undefined behavior. `string` can only hold 8 characters (7 for "october" and 1 for the null terminator). When you call `strcpy`, you are writing 10 characters to it (9 for "september" and 1 for the null terminator), which means you have gone past the end of the array and are overwriting the adjacent memory. – Marlon Mar 30 '12 at 04:55
  • 14
    Note that `sizeof` is calculated at *compile* time where as `strlen` is run time. – Naveen Mar 30 '12 at 04:57
  • 5
    @Naveen: Be aware that that is not necessarily true where VLAs are involved. – caf Mar 30 '12 at 05:31
  • @caf: Maybe I'm gonna feel clueless but..... What do you mean by VLAs? Very large arrays? lol – Cory Gross Aug 07 '13 at 06:41
  • @CoryGross: A "variable length array", an array type where the length is not an integer constant expression (or the element type is itself a variable length array type). – caf Aug 07 '13 at 07:04
  • @caf: So your saying `sizeof` can be used on a dynamically allocated array and in this context will not be calculated at compile time? – Cory Gross Aug 07 '13 at 07:28
  • 2
    I am saying that in the function `int foo(int n) { int a[n];` the value `sizeof a` is not calculated at compile-time. – caf Aug 07 '13 at 07:49

3 Answers3

41

sizeof and strlen() do different things. In this case, your declaration

char string[] = "october";

is the same as

char string[8] = "october";

so the compiler can tell that the size of string is 8. It does this at compilation time.

However, strlen() counts the number of characters in the string at run time. So, after you call strcpy(), string now contains "september". strlen() counts the characters and finds 9 of them. Note that you have not allocated enough space for string to hold "september". This is undefined behaviour.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
Sean
  • 5,290
  • 2
  • 24
  • 21
  • Yeah, even after copying "September", its still giving correct length of string despite we don't know the 9th position contains null character or not! – Dr. Essen Mar 20 '18 at 14:26
1

The Output is correct because

first statement string size was allocated by compiler that is 7+1 (October is 7 bytes & 1 byte for null terminator at compile time)

Second statement: you are copying September (9 bytes to 8 bytes string);

there for you got size of September as 8 bytes (still strlen() will not work for September it does not have null character)

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • 3
    The string literal `"september"` implicitly contains the null character, so `strlen()` will work, if the program hasn't crashed already (due to writing past the end of the `string` array) – Timothy Jones Mar 30 '12 at 05:17
  • @TimothyJones: It's undefined behavior, so technically, there are options besides "crash" or "work". Never discount the possibility of nasal demons. – ShadowRanger Mar 31 '21 at 14:39
0

Your destination array is 8 bytes (length of "october" plus \0) and you want to put in 9 chars in that array.

man strcpy says: If the destination string of a strcpy() is not large enough, then anything might happen.

Please tell me what you really want to do, because this smells bad long way

ola1olsson
  • 253
  • 1
  • 2
  • 11