1

Here's what I did:

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

int main() {

    char name[] = "longname";
    printf("Name = %s \n",name);
    strcpy(name,"evenlongername");
    printf("Name = %s \n",name);
    printf("size of the array is : %d",sizeof(name));
    return 0;

}

It works, but how? I thought that once memory is assigned to an array in a program, it is not possible to change it. But, the output of this program is:

Name = longname 
Name = evenlongername 
size of the array is 9

So the compiler affirms that the size of the array is still 9. How is it able to store the word 'evenlongername' which has a size of 15 bytes (including the string terminator)?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Krish
  • 575
  • 4
  • 9
  • 3
    Undefined behavior includes working perfectly fine. – Neil Nov 14 '18 at 19:15
  • 1
    Accidents will happen; it is an accident that it works. It was not guaranteed to work; it was not guaranteed to fail. You have undefined behaviour, and any response is legitimate. Also, in this context, `sizeof()` is evaluated at compile time and doesn't change the result at runtime. – Jonathan Leffler Nov 14 '18 at 19:21

3 Answers3

6

In this case, name is allocated to fit "longname", which is 9 bytes. When you copy "evenlongername" into it, you're writing outside of bounds of that array. It's undefined behavior to write outside of the bounds, this means it may or may not work. Some times, it'll work, other times you'll get seg fault, yet other times you'll get weird behavior.

Kon
  • 4,023
  • 4
  • 24
  • 38
3

So the compiler affirms that the size of the array is still 9. How is it able to store the word 'evenlongername' which has a size of 15 bytes(including the string terminator)?

You are using a dangerous function (see Bugs), strcpy, which blindly copies source string to destination buffer without knowing about its size; in your case of copying 15 bytes into a buffer with size 9 bytes, essentially you have overflown. Your program may work fine if the memory access is valid and it doesn't overwrite something important.

Because C is a lower-level programming language, a C char[] is "barebone" mapping of memory, and not a "smart" container like C++ std::vector which automatically manages its size for you as you dynamically add and remove elements. If you are still not clear about the philosophy of C in this, I'd recommend you read *YOU* are full of bullshit. Very classic and rewarding.

Cyker
  • 9,946
  • 8
  • 65
  • 93
  • 2
    `strcpy()` is not dangerous. It is an optimized function for a particular task. If a coder needs to use "safe" functions even without understanding them, C is not the a language to use. – chux - Reinstate Monica Nov 14 '18 at 19:33
  • @chux well, that depends on how much an expert you are; i think most of the time it doesnt hurt calculating and adding the destination buffer size; but you are free to omit that if you are confident; if `strcpy` is really that safe to use then there isnt a reason to add `strncpy`? – Cyker Nov 14 '18 at 19:36
  • 2
    `strncpy()` is not a "safe" version of `strcpy()`. Each has its place for different tasks. – chux - Reinstate Monica Nov 14 '18 at 19:40
  • @chux `strncpy()` is a "safer" version of `strcpy()`, in the sense that `strncpy()` is overflow-safe but `strcpy()` isnt; but you are still free to use either if you know that would work correctly in your program; – Cyker Nov 14 '18 at 19:47
  • This is not only my view, [Why should you use strncpy instead of strcpy?](https://stackoverflow.com/a/1258577). The accepted answer promoting `strncpy()`, 109 Up and 26 down votes. The higher rated [answer](https://stackoverflow.com/a/1258577/2410359) which does not promote `strncpy()` as safer has 152 up and 0 down votes. – chux - Reinstate Monica Nov 14 '18 at 19:52
  • @chux that link is helpful; my point is `strncpy()` is not by origin a bounded `strcpy()`, but in effect works almost like a bounded `strcpy()`; if you think neither is safe enough then you dont have to use any ([1](https://github.com/git/git/commit/c8af66ab8ad7cd78557f0f9f5ef6a52fd46ee6dd), [2](https://github.com/git/git/commit/e488b7aba743d23b830d239dcc33d9ca0745a9ad)); – Cyker Nov 14 '18 at 20:13
2

Using sizeof on a char array will return the size of the buffer, not the length of the null-terminated string in the buffer. If you use strcpy to try and overflow the array, and it just happens to work (it's still undefined behavior), sizeof is still going to report the size used at declaration. That never changes.

If what you're interested in is observing how the length of a string changes with different assignments:

  1. Use an adequate buffer to store every string you're going to test.
  2. Use the function strlen in <string.h> which will give you the actual length of the string, and not the length of your buffer, which, once declared, is constant.
Govind Parmar
  • 20,656
  • 7
  • 53
  • 85