Home > Mobile >  Is character array size dynamic in C/CPP/C ?
Is character array size dynamic in C/CPP/C ?

Time:11-15

My knowledge till now was that arrays in C and CPP/C have fixed sizes. However recently I encountered 2 pieces of code which seems to contradict this fact. I am attaching the pics here. Want to hear everyone's thoughts on how these are working. Also pasting the code and doubts here:

1.

#include <iostream>
#include <string.h>

using namespace std;

int main()
{
    char str1[]="Good"; //size of str1 should be 5
    char str2[]="Afternoon";  //size of str2 should be 10
    
    cout<<"\nSize of str1 before the copy: "<<sizeof(str1);
    cout<<"\nstr1: "<<str1;
    
    strcpy(str1,str2);     //copying str1 into str2      
    
    cout<<"\nSize of str1 after the copy: "<<sizeof(str1);
    cout<<"\nstr1: "<<str1;

    return 0;
}

your text O/P: Size of str1 before the copy: 5 str1: Good Size of str1 after the copy: 5 str1: Afternoon

In first snippet I am using strcpy to copy char str2[] contents that is "Afternoon" into char str1[] whose size is 5 less than size of str2. So theoritically the line strcpy(str1,str2) should give error as size of str1 is less than size of str2 and fixed. But it executes, and more surprising is the fact that even after str1 contain the word "afternoon" the size is still the same.

2.

#include <iostream>
#include <cstring>

using namespace std;
int main()  
{  
    char first_string[10]; // declaration of char array variable  
    char second_string[20]; // declaration of char array variable  
    int i;  // integer variable declaration  
    
    cout<<"Enter the first string: ";  
    cin>>first_string;  
    cout<<"\nEnter the second string: ";  
    cin>>second_string;  
    
    for(i=0;first_string[i]!='\0';i  );   
      
      
    for(int j=0;second_string[j]!='\0';j  )  
    {  
        
        first_string[i]=second_string[j];  
        i  ;  
    }  
    first_string[i]='\0';  
   cout<<"After concatenation, the string would look like: "<<first_string;  
return 0;  
}

O/P: Enter the first string: good

Enter the second string: afternoon

After concatenation, the string would look like: goodafternoon

Here also even if I provide a string of length 20 as input to second_string[] it's still able to concatenate both the strings and put them in first_string[], even though the size of the concatenated string will be clearly greater than size of first_string[] which is 10.

I tried to assign a string of greater length to a string variable of smaller length. techincally it should not work but it worked anyway

CodePudding user response:

There are two misunderstandings here

  1. sizeof is the size of the array at compile time. It has nothing to do with the contents of the array. You can change the contents all you like and sizeof will still be the same. If you want the length of a string use the function strlen.

  2. Most of the time when you break the rules of C it leads to undefined behaviour. Copying a string into an array that is too small to hold that string is one example of undefined behaviour.

You said

So theoritically the line strcpy(str1,str2) should give error as size of str1 is less than size of str2 and fixed.

This is untrue. Undefined behaviour does not mean that there must be an error. It means exactly what it says, the behaviour of your program is undefined, anything could happen. That might mean an error message, or it might mean a crash, or it might mean that your program seems to work. The behaviour is undefined.

You aren't alone in thinking as you did. I reckon the purpose of sizeof and the nature of undefined behaviour are two of the commonest beginner misunderstandings.

And to answer the question in the title. The size of a character array is fixed in C , nothing in your example contradicts that.

CodePudding user response:

I've honestly never seen a C programmer write char stringname[20] = "string";, that just isn't the way you'd handle strings in C ⁰.

And neither would a C programmer use array notation, because well, it's not really an array you're getting, you're getting a char*: which isn't quite the same, because sizeof of an array is the compile time object size, which is a pointer size for a pointer, and the array length times the individual object (assuming the size is alignable, which is the case for char[]) for an array.

Your access beyond the end of an array is simply a bug. It is undefined behaviour. A buffer overflow. A static code analyzer, quite possibly even a compiler, would tell you that this is a mortal sin. The str* functions know literally nothing about the size of your array, they only see a pointer to the first element, and your array literally knows nothing about the length of the string it contains, which is given by the terminating zero character's position. You're mixing up two things here!

In C , you'd definitely use the std::string class to read from cin, exactly to avoid the problem with buffer overflows.

So, honestly: If you're a C beginner, maybe try to ignore C strings for now. It's not a C way of dealing with string data other than fixed string literals (i.e., things between "" in your source code), and the C way of string handling is literally still the dominant cause for remote-exploitable bugs in software, far as I can tell. C is not C, and, honestly, when it comes to handling strings, for the better. Including both <string.h> and <iostreams> is a pretty reliable indication of a programming beginner who has access to bad guides that treat C as extended C. But that's simply not true; it's a very different programming language with some far-reaching C compatibility, but you would, and should, not mix these two languages – as a beginner, it's hard enough to learn one¹.


⁰ Technically speaking, it even feels wrong; a string literal in C is a const char pointer, whereas it's just a char pointer in C. C and C are not the same language.

¹If you feel like you're explaining C to people, and sometimes feel overwhelmed with making a good explanation for things to people who are not expert C programmers already, Kate Gregory made a nice talk why teaching C to teach C is a really bad idea, which I agree to, even if she overstresses a few points.

  • Related