Dynamic memory allocation in C++ language [duplicate] - c++

This question already has answers here:
Char and strcpy in C
(5 answers)
Closed 2 years ago.
I want to allocate space for char array (string) in C++. When I allocate memory for 10 chars, I can also assign more characters to the char array. When I print it, it gives some of the additionally assigned characters from the array.
#include <string.h>
using namespace std;
int main()
{
char *name = new char[10];
strcpy(name, "MoreThanTenCharacters");
cout << name << endl;
}
Although the allocated memory is for 10 characters, I can assign more. Printing gives exactly the same value. What is the logic behind it?

When the buffer pointed by the first argument is shorter than the string pointed by the second argument (taking the null terminator into consideration), then the copy will overflow the buffer into surrounding memory, and the behaviour of the program is undefined.
Printing gives exactly the same value. What is the logic behind it?
You've observed some behaviour. This is an example of possible behaviours that the program could have when the behaviour is undefined.
So, what is the correct way of allocating memory for JUST 10 chars and assigning a string to it?
Your allocation is correct although not ideal. Using a bare pointer is unsafe; in the end you leak the allocation. It's the copying where your bug happens.
An efficient and simple option is to use std::string. If your goal is to store the 10 character long prefix substring of the input, then following would be correct:
std::string name("MoreThanTenCharacters", 10);

Related

C++ Size of char* buffer [duplicate]

This question already has answers here:
How to get the real and total length of char * (char array)?
(15 answers)
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 2 years ago.
Is there a way to determine the size of a char[] buffer via a char* pointer in C++? I'm using C++98.
The following lines of code all print out '8' (essentially sizeof(char*)). However I'm looking for the actual size of the buffer.
int maxBufferLen = 24;
char* buffer = new char[maxBufferLen];
std::cout << sizeof(buffer) << std::endl; // prints '8'
std::cout << ( sizeof(buffer) / sizeof(buffer[0]) ) << std::endl; // prints '8'
In practice, I am passing that char* buffer in between functions and I will not have access to the maxBufferLen variable that I am using to initialize it. As such, I'll need to determine the length using another way.
There is general no way of determining the size of an array based on a pointer to an element of that array.
Here are typical ways to find out the size:
Store the size in a variable
A variant of this is to store both the pointer and the size (or alternatively, pointer past the end) as members of a class. An example of this approach is the std::span class template (this standard class is not in C++98, but you can write your own, limited version).
A variant this, which is generally used when the array is allocated dynamically (such as in your example), is to deallocate the memory in the destructor of the class and conforming to the RAII idiom. Examples of this approach are std::string and std::vector.
Or choose certain element value to represent the last element of the array. When iterating the array, encountering this "terminator" element tells you that the end has been reached. This is typically used with character strings, especially in C interfaces, where the null terminator character ('\0') is used.

can we declare size of a pointer

can we declare size to a pointer
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char (*ptr)=new char[3];
strcpy(ptr,"ert");
cout<<ptr<<endl;
return 0;
}
what is the meaning of this line char *ptr=new char[3] if it allocates size to ptr.since i have given the size as 3 and the string as "ert"it has to show error since the string length is too long but it doesn't .can we allocate size to pointers if so how?
You need 4 characters:
char *ptr=new char[4];
strcpy(ptr,"ert");
One extra space for the nul terminator:
|e|r|t|\0|
It's not the size of the pointer that you've declared, but the size of the character array that the pointer points to.
strcpy() does not know the length of the array that the pointer points to - it just knows it's got a pointer to the first byte it can copy into, and trusts that you know there's enough room for the copy to be made. Thus it's very fast, but it's also rather dangerous and should be used only when you're sure the destination is large enough.
strncpy() is worth looking into for some extra safety, but you still have to know that the target pointer points to something large enough for the size you specify (it protects more against the size of the source than the size of the target).
The lesson to learn here is that C and C++ won't give you any help - the compiler trusts you to get your buffer sizes right, and won't do any checking on your behalf either at compile time or runtime. This allows programs to run extremely fast (no runtime checking) but also requires the programmer to be a lot more careful. If you're writing in C++ which your tags suggest, for normal string handling you should definitely be using the std::string class unless you have a specific reason to need C-style string handling. You may well have such a reason from time to time, but don't do it unless you have to.
This statement
char (*ptr)=new char[3];
at first allocates in the heap unnamed character array with 3 elements and then the address of the first element of the array is assigned to pointer ptr.
The size of the pointer will not be changed whether you initialize it as in the statement above or the following way
char (*ptr)=new char;
that is sizeof( ptr ) will be the same and equal usually either to 4 or 8 bytes depending on the environment where the program will be compiled.
C++ does not check bounds of arrays. So in this statement
strcpy(ptr,"ert");
you have undefined behaviour of the program because string literal "ert" has four elements including the terminating zero.

C Style Strings Difference : C/C++ [duplicate]

This question already has answers here:
What is the difference between char a[] = ?string?; and char *p = ?string?;?
(8 answers)
Closed 9 years ago.
What is the difference between C Style Strings
char str[10]="Hello";
char str[]="Hello";
char* str= "Hello";
1) I believe that char str[10]="Hello" is automatic variable and stored on the stack.True? i.e. Allocates 10 bytes on stack.
2) Does char str[]="Hello"; is also stored on stack? i.e. allocates 6 bytes - including null character on stack.
3) Does char* str= "Hello"; stores pointer str on stack and the object "Hello" is stored on heap? i.e. allocates 6 bytes - including null character on heap.
4) All strings (in question 1,2 and 3) are null terminated . True/False?
5) Whether it is C or C++ whenever we create an string like "Hello" , it is always null terminated. Suppose in C++ we declare string str = "Hello"; , is it also null Terminated?
EDIT
Consider All declared in main().
#Negative points and close requests. I am asking this question with respect to where they are stored heap or stack? And also null termination.
"Consider All declared in main()."
Then
1) Yes.
2) Yes.
3) Yes, and no (it's stored neither on the stack nor in the heap in common implementations). "i.e. allocates 6 bytes" -- you seem to have forgotten about the memory required for the pointer. Also, there's an erroneous claim in the comments and in another answer that char* str= "Hello"; is wrong, but in fact it is legal C and, for now, legal C++ ... see What is the type of string literals in C and C++?
4) True, but it would be false if you changed 10 to 5 -- that is, given char str[5]="Hello";, str is not NUL-terminated.
5) False and no (although the implementation might store a NUL following the string -- C++11 requires it -- but that isn't part of the string).
"I am asking this question with respect to where they are stored heap or stack?"
Where do people get the idea that these are the only sorts of memory? Local variables are stored on the stack and memory allocated via malloc or (non-placement) new is allocated from the heap. Program code, file-scope variables, and literals fall into neither of those categories.
You are looking at this kind of sideways, which is probably why you are confused ;-)
1) If these variables are all declared inside a routine definition, without the static keyword, then they are all on the stack.
BUT char str[10] and char str[] are arrays - you get all characters of the array on the stack.
char *str is a pointer to one or more characters. Only the pointer is sure to be on the stack.
2) "Hello" always represents a NULL terminated string in C - it's 6 char's long. If you wanted to initialize a character array to contain a set of characters which is not NULL terminated, you can't do it this way.
3) As people have pointed out in the comments, it's unclear what char *str = "Hello"; does, or even whether it's legal. If it were char const *str = "Hello"; and the compiler accepted it, I'd expect to find the 6 character string somewhere anonymous, global, and possibly protected.
4) I haven't a clue what the "string" class does in C++.

Memory Usage estimation [duplicate]

This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 10 years ago.
I am wondered about the memory usage of variables and I tried this :
#include <iostream>
int main()
{
char* testChar1 = "Hi";
char* testChar2 = "This is a test variable";
char* testChar3 = "";
std::cout <<sizeof(testChar1)<<std::endl;
std::cout <<sizeof (testChar2) <<std::endl;
std::cout <<sizeof(testChar3)<<std::endl;
}
output is :
4
4
4
I think I am not doing the right thing. I want to know how much memory every variable uses in stack .
EDIT 1
At the same time if I does char* testChar3 = NULL; the program crashes. So does it mean there is no memory usage for the same?
In addition to using strlen, you could also use sizeof on a
char testChar1[] = "Hi";
EDIT: yes, this includes the null terminator, which IMO is an advantage over strlen. The actual size does include the null terminator.
You simply print the size of the pointers, they always will be the same. What you need is to multiply strlen for the strings by the size of a single char.
EDIT: as per my comment and the correction from #Suma:
cout << (strlen(testChar) + 1) * sizeof(char) + sizeof(testChar);
The 1 is needed for the terminating zero character.
sizeof(testChar1) return size of pointer, if you want to test string length try replace sizeof with strlen
In this instance you're only printing the size of the pointers and not the chars. So really, you would want to print the pointer, then dereference it and print the size of the memory it points to as well.
You are actually printing the amonut of bytes a pointer takes on your system . I think what you need to do is to use strlen function . Check it out here . strlen
std::cout<<strlen(testChar1)<<std::endl;
std::cout <<strlen(testChar2) <<std::endl;
std::cout <<strlen(testChar3)<<std::endl;
I want to know how much memory every variable uses in stack .
What your programm print is exactly what you want.
Read the other answer if what you really want is to know how much memory (where??!!) occupy the char-strings pointed by yours variables - pointers.

Why my source is changing when using strcpy in c

After using strcpy source is getting corrupted and getting correct destination. Following is my code please suggest me why my source is getting corrupted? If i keep a fixed size to second character array q[] then my source is not being changed. Why is this strange behaviour. -
I am using MSVC 2005
void function(char* str1,char* str2);
void main()
{
char p[]="Hello world";
char q[]="";
function(p,q);
cout<<"after function calling..."<<endl;
cout<<"string1:"<<"\t"<<p<<endl;
cout<<"string2:"<<"\t"<<q<<endl;
cin.get();
}
void function(char* str1, char* str2)
{
strcpy(str2,str1);
}
OUTPUT:
after function calling...
string1: ld
string2: Hello world
Thanks in advance,
Malathi
strcpy does not allocate memory required to store the string.
You must allocate enough memory in str2 before you do the strcpy.
Otherwise, you get undefined behaviour as you are overwriting some non-allocated memory.
q has only space for 1 character which is the terminating \0.
Please read a book about C - you need to learn something about memory management.
Most likely your memory looks like this (simplified): Qpppppppppppp. So when you strcpy to q, you will overwrite parts of p's memory.
Since you are using C++: Simply use std::string and or std::stringstream instead of raw char arrays.
In your code, q, is an one-element array (basing on the length of "", which is equal to one due to the null terminator), so it cannot contain the whole string. Hence you can't do a strcpy because it writes over invalid memory location (tries to write too much data to an array).
Declare q to be big enough to contain your string. Also, you can use strncpy to be on the safe side.
char q[] = ""; creates a character array with exactly 1 element - copying more data into it won't reserve more memory for it.
So, what happens is that when you write past the space reserved for q, you start overwriting what's in p - the two variables are next to each other in memory.
What everyone is saying is half correct. The code is failing because space is not reserved for the copy as others have pointed out correctly. The part that's missing is that your objects are on the stack, not the heap. Therefore it is not only likely, but inevitable that your code will get corrupted as the stack can no longer be unwound.
The array "q" is just one byte long; it definitely doesn't have room for the string "Hello, World"! When you try to copy "Hello, World" to q, you end up exceeding the bounds of q and overwriting p, which is adjacent to it on the stack. I imagine drawing a diagram of how these things are laid out on the stack, you could determine exactly why the garbage that ends up in p is just "ld".
strcpy expects you to provide an allocated storage buffer, not just a char* pointer. If you change char q[]=""; to char q[50]; it will work. Since you're only giving strcpy a pointer to a zero length string it doesn't have enough space to store the copied string and overwrites aka corrupts the memory.