Strcpy behavior with stack array c++

strcpy c
strlcpy
strncpy in c
strlcpy vs strncpy
strcpy vs strncpy
strncpy buffer overflow
strcpy implementation in c
strcpy(buffer overflow)

Here is my program :

#include <cstring>
const int SIZE =10; 

int main() 
{ 
    char aName [SIZE]; // creates an array on the stack
    std::strcpy(aName, "Mary");
    return 0;
}

This program is obviously useless, I am just trying to understand the behavior of the strcpy function.

Here is it's signature : char * strcpy ( char * destination, const char * source )

so when I do : std::strcpy(aName, "Mary");

I am passing by value the variable aName. I know that the aName (in the main) contains the address of the array. So is this assertion correct : strcpy creates a local variable called destination that has as value the address of the array aName that I have created on the stack in the main function?

I am asking this because it is very confusing to me. Whenever I have encountered addresses it usually was to point to a memory allocated on the heap...

Thanks!

Whenever you encounter addresses it doesn't mean it will always point to memory allocated to heap.

You can assign the address of a variable to a pointer like this

int a=5;
int *myPtr= &a;

Now, myPtr is a pointer of type integer which points to the memory of variable which is created on stack which is a have value 5.

So, whenever you create a pointer and assign the (address of) memory using new keyword, it will allocate the memory on heap. So, if I assign the value like this it will be on stack

int *myPtr= new int[5];

Why strcpy and strncpy are not safe to use?, All Data Structures � Array � LinkedList � Stack � Queue � Binary Tree � Binary strcpy() function in C/C++ Using strcpy() function to copy a large character array into smaller one is If destination string is not large enough to store the source string then the behavior of strcpy() is unspecified or undefined. When you use undefined behavior in C, the behavior you get is dependent on your compiler and your machine which can do what ever they like. Computers are deterministic by nature and everything they do is defined by the code that they run so it is possible to define undefined behavior if you dig deep enough.

So is this assertion correct : strcpy creates a local variable called destination that has as value the address of the array aName that I have created on the stack in the main function?

Yes.

Whenever I have encountered addresses it usually was to point to a memory allocated on the heap...

Yep, usually. But not always.

Pointers to non-dynamically-allocated things are fairly rare in C++, though in C it's more common as that's the only way to have "out arguments" (C does not have references).

strcpy is a function from C's standard library.

STRCPY in C, STRCPY in C is a C standard library function that copies a string. A pointer to a string is merely a pointer to the first character in this array. If we try to change the contents of a string literal in C, we'll encounter some unfortunate behavior. AR / VR � Low Level and Algorithms � Machine Learning � Web Stack Development� The syntax of the strcpy() function is: Syntax: char* strcpy (char* destination, const char* source); The strcpy() function is used to copy strings. It copies string pointed to by source into the destination. This function accepts two arguments of type pointer to char or array of characters and returns a pointer to the first string i.e destination.

Maybe it would help to look at an example implementation of strcpy():

char* strcpy(char* d, const char* s)
{
    char* tmp = d;

    while (*tmp++ = *s++)
        ;

    return d;
}

That's really all there is to it. Copy characters from the source to the destination until the source character is null (including the null). Return the pointer to the beginning of the destination. Done.

Pointers point to memory. It doesn't matter if that memory is "stack", "heap" or "static".

strcpy, strcpy_s, The behavior is undefined if either dest is not a pointer to a character array or src is not a pointer to a null-terminated byte string. 2) Same as (1),� Any attempt to modify a strig literal results in undefined behavior of the program. From the C Standard (6.4.5 String literals) 7 It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined.

Function parameters are its local variables.

In this call

std::strcpy(aName, "Mary");

the two arrays (one that is created in main with the automatic storage duration and other is the string literal that has the static storage duration) are implicitly converted to pointers to their first elements.

So you may imagine this call and the function definition the following way

std::strcpy(aName, "Mary");

 // …

char * strcpy ( /* char * destination, const char * source */ )
{
    char *destination = aName;
    const char *source = "Mary";

    // …

    return destination;
}

Or even like

char *p_to_aName = &aName[0];
const char *p_to_literal = &"Mary"[0];
std::strcpy( p_to_aName, p_to_literal );

 // …

char * strcpy ( /* char * destination, const char * source */ )
{
    char *destination = p_to_aName;
    const char *source = p_to_literal;

    // …

    return destination;
}

That is within the function its parameters are local variable of pointer types with the automatic storage duration that are initialized by pointers to first characters of the passed character arrays

Buffer Overflow, Buffer overflows may occur on the stack, on the heap, in the data segment, program behavior (usually leading to a segfault), or hijack the program's flow. To make the above example safe, assigned a value for the array index Most standard library functions in C do not do bounds checking , including strcpy() , strcat(),� The strcpy () function is used to copy the source string to destination string. If the buffer size of dest string is more then src string, then copy the src string to dest string with terminating NULL character. But if dest buffer is less, then src then it will copy the content without terminating NULL character.

So is this assertion correct : strcpy creates a local variable called destination that has as value the address of the array aName that I have created on the stack in the main function?

Yes. That is correct. Though I probably wouldn't call it a local variable. It is a parameter. Local variable usually means something like this:

int localVariable;

The word'parameter" is often associated with things like this:

int myFunction(int parameter) {
    // use parameter some where...
}

The point is roughly the same though: it creates a variable that will go out of scope once the function exits.

I am asking this because it is very confusing to me. Whenever I have encountered addresses it usually was to point to a memory allocated on the heap...

Yes, this is the most common use case for them. But it isn't their only use. Pointers are addresses, and every variable has an address in memory regardless of whether it is allocated on the "heap" or "stack."

The use here probably because pointers to a char are commonly used to store strings, particularly on older compilers. That combined with the fact that arrays "decay" into pointers, it is probably easier to work with pointers. It is also certainly more backwards compatible to do it this way.

The function could have just as easily used an array, like this:

char * strcpy ( char destination[], const char source[ )

But I'm going to assume it is easier to work with pointers here instead (Note: I don't think you can return an array in C++, so I'm still using char *. However, even if you could, I would imagine it is still easier to work with pointers anyway, so I don't think it makes a lot of difference here.).


Another common use of pointers is using them as a way to sort of "pass by reference":

void foo(int * myX) {
    *myX = 4;
}

int main() {
    int x = 0;

    foo(&x);

    std::cout << x; // prints "4"

    return 0;
}

However, in modern C++, actually passing by reference is preferred to this:

void foo(int & myX) {
    myX = 4;
}

int main() {
    int x = 0;

    foo(x);

    std::cout << x; // prints "4"

    return 0;
}

But I bring it up as another example to help drive the point home: memory allocated on the heap isn't the only use of pointers, merely the most common one (though actually dynamically allocated memory has been mostly replaced in modern C++ by things like std::vector, but that is beside the point here).

Buffer Overflows in C - Department of Computer Science, Vulnerabilities when Using Arrays - Length Faults (cont.) Copy a source string into a target/destination string using strcpy() foo: 00401000 bar: 00401045 Stack (Before): 00000000 00000000 7FFDF000 0012FF80 0040108A 00410EDE Behavior: If type is 0 or 2 then size_t __builtin_object_size(p, type) returns� char * strcpy ( char * destination, const char * source ); Copy string Copies the C string pointed by source into the array pointed by destination , including the terminating null character (and stopping at that point).

Is initializing a char[] with a string literal bad practice?, It's anyways bad practice to initialie a char array with a string literal. as C), that's pretty much the only way to initialize an array of char with a string value strncpy (string, "october", sizeof string); // only copies as many characters as So if you pass this char[] to method who changes data you can have interesting behavior. Description. The C library function char *strcpy(char *dest, const char *src) copies the string pointed to, by src to dest.. Declaration. Following is the declaration for strcpy() function.

Top 20 C pointer mistakes and how to fix them, Pointers are the most complicated and fundamental part of the C Memory on the stack(non-pointer variables) is done implicitly by the system. This'll end in undefined behavior – maybe crashes depending on the state of the Never use sizeof on a pointer to an array to determine the size of the array. strcpy, strcpy_s. 1) Copies the null-terminated byte string pointed to by src, including the null terminator, to the character array whose first element is pointed to by dest. The behavior is undefined if the dest array is not large enough. The behavior is undefined if the strings overlap.

Dynamic Strings in C and a Crash Course in Pointers, Since C has no string type, we use arrays of characters to represent something like a full Recall that stack memory requirements are determined at is considered “Undefined Behavior”–code word in the C specificiations manual for for(int i=0; i<strlen(full_name); i++) { printf("[%d] %c\n", i, full_name[i]); }. The function strcpy (think, "string copy") is a C standard library function that copies a string. ASIDE - STRING REFRESHER When working with strings in C, remember - strings are no more than arrays of ASCII-encoded characters ending with a terminating null byte (\0). A pointer to a string is merely a pointer to the first character in this array.

Comments
  • I dont' know if I understand your question correctly. A pointer can point anywhere, not just to the heap. if you want to know, where string literals are stored, you might find this question helpful.
  • In the declaration char * strcpy ( char destination[], const char source[] ) both destination and source are pointers. In almost all contexts, the name of an array decays into a pointer to its first element. So that function declaration means exactly the same thing as char * strcpy ( char *destination, const char *source ). This is a common source of confusion for newcomers.
  • Could you give me a source to back that up? It's not that I think you're wrong, but would like to read a more in-depth explanation to make sure I understand properly..
  • Google "array to pointer decay". You’ll find a bunch of stuff.
  • I mean, I did and found this which already has a place in my answer. So perhaps I'm still not understanding what you mean.
  • @PeteBecker To be pedantic, It isn't technically directly because of the decaying why char destination[] is equal to char* destination in an argument declaration, right? It is because of the complementary rule of type adjustment. The array type is adjusted to be the pointer type in the argument declaration. @Chipster It's really unclear why you "assume it is easier to work with pointers here instead" considering that you are working with pointers regardless of which type you declare (because it will be a pointer after the adjustment either way).
  • But if aName does not contain the adress of the array. How come strcpy still accepts it as an argument if strcpy's arguments are pointers (therefore there values are adresses)?
  • @CSstudZ Because of the implicit conversion.
  • Implicit conversion of an array means taking an array as an argument and using it's address ?
  • @CSstudZ In C++ some values can be implicitly converted from one type to another. For example, if there is a function that accepts an int , you can pass a 5.2 into the function, then the value will be implicitly converted to the type int and the converted value will be 5. This is an implicit conversion. Similarly, if a function accepts a pointer to char, and you pass an array of 10 char instead, then there is an implicit conversion. The array will be converted to pointer to char, and the converted value will be address of the first element.