Strcat() returns garbage after strcpy [duplicate] - c++

This question already has answers here:
functions returning char pointer
(12 answers)
Closed 7 years ago.
Why this does not work? With strcat commented it returns first char * OK, but with strcat uncommented i get garbage characters.
char * concat(char* first, char* second){
char result[10]; // array to hold the result.
strcpy(result,first); // copy string one into the result.
strcat(result,second); // append string two to the result.
return result;
}
concat(rPlayer.name,"blbost");

You're returning an address to first element of an array which is local to the function which is no longer valid(/exists) after the function returns.
The first should have the contents of the second array appended to it. You need to be sure that the first has enough space already allocated to append all of the characters from the second array so as not to run into undefined behavior.

Related

C-Style Character String [duplicate]

This question already has answers here:
Concatenate char arrays in C++
(7 answers)
C++ concatenate two int arrays into one larger array
(6 answers)
Fastest way to append two arrays ( concatenate two arrays) C++
(7 answers)
Closed 8 months ago.
I want to connect two C-style character strings and store the result in a dynamic char array.
int main()
{
char word1[] = "hello";
char word2[] = "haha";
auto ptr = new char[20];
strcpy(ptr,strcat(word1,word2));
cout<<ptr<<endl;
return 0;
}
The compiler says there is a "segmentation fault" at the statement strcpy(ptr,strcat(word1,word2));. Why does the compiler say that?
Like this
strcpy(ptr, word1);
strcat(ptr, word2);
You need to use ptr for both operations, the copy and the concatenation.
In your version strcat(word1,word2) tries to concatenate word2after the end of word1. But there is no accessible memory there, so you get a segmentation fault.

Dynamic memory allocation in C++ language [duplicate]

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);

Intricacies of strcpy_s in C++ [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 7 years ago.
I am having a difficult time obtaining the correct size of a string in order to satisfy strcpy_s. For example if I specify
char buffer = {0};
char *str1 = (char*)&buffer;
strcpy_s(str1,sizeof("This is a string\n"),"This is a string\n");
Then it will work as expected. If however I declare the following:
char buffer = {0};
char *str1 = (char*)&buffer;
const char* string1 = "This is a string.....";
strcpy_s(str1, ?????,string1);
If I use anything other than a literal in place of ????? it will fail with a memory exception, for example if I use std:strlen(str1), etc. Any size literal for ???? will work. Of course using a fixed literal is not acceptable.
This is a major re-edit of the original question and I apologise to the people who have answered to date. However none of the the answers below have worked.
"This is a string" is a character array. When you say sizeof(Array)/sizeof(type) it will give the size of the array
When you define the string as const char* then the sizeof(pointer) gives the size allocated for the pointer no the array size
const char* ptr = "This is a string\n";
std::cout<<sizeof("This is a string\n")<<std::endl; //==>18
std::cout<<sizeof(ptr)<<std::endl; //==>4
First of all, the second parameter is the size of the destination buffer, not the size of the source buffer.
so the correct way is:
char str1[100];
strcpy_s(str1, sizeof str1, "Whatever string");
or
int n = 100;
char *str1 = new char[n];
strcpy_s(str1, n, "whatever string");
For an array (first example) sizeof returns the size of the array.
For a pointer (second example) sizeof returns the size of the pointer (which is not what you want)
In your second example, string1 is of type const char*. sizeof will return the size of the pointer, rather than the length of the string literal you are pointing to.
The first example works because a string literal is a const char[], and sizeof will correctly return the length of the string (but with the null terminating character as well). It's only coincidental that this works because char is 1 byte. Do not use sizeof to get string lengths.
To make your second example work, try using std::strlen.

The value of the pointer to char address [duplicate]

This question already has answers here:
cout << with char* argument prints string, not pointer value
(6 answers)
Closed 7 years ago.
In VS C++ I have a simple declaration of a char variable and a pointer to char.
char mychar = 'c';
char *mypointer = &mychar;
When printing the value of mypointer using cout I would expect an 8 character address value like 0038FEDC to appear in console. Instead I am getting some strange results like:
c│■8, ck∙<, c;■8 etc...
Why these strange characters appear when outputting pointer to char values?
std::ostream, of which std::cout is an instance, has an overload for operator<< which treats char* as a pointer to the first character in a null-terminated string.
You are passing it a pointer of a single character, not a null terminated string. This causes undefined behaviour.
In practice what is likely to happen is that a stream of characters will be printed out by treating the memory starting from mychar as an array of char and iterating over it, until a \0 is found.
If you want to print the address, you can cast the pointer to something that isn't char*:
std::cout << static_cast<void*>(mypointer) << std::endl;

string type doesn't work properly unless passed by reference [duplicate]

This question already has answers here:
how to set char * value from std string (c_str()) not working
(5 answers)
Closed 8 years ago.
I faced the problem in a bigger project so I made a test class hoping I can identify and solve it:
class test_class{
public:
int length;
const char* cstr;
test_class(){cstr = nullptr; length = 0;}
void SetStr(string str){cstr = str.c_str(); length = str.length();}
};
So when I use the SetStr member function, the first character in cstr behaves like a null-terminator. The following code is an example:
string str5="abcdefg";
test_class test;
test.SetStr(str5);
cout<<test.cstr<<endl;
cout outputs nothing, but the characters after the first one are valid. So if I print them with a loop, I get the whole string except for the first character.
But if I rewrite the SetStr function as follows(adding the &):
void SetStr(string& str){cstr = str.c_str(); length = str.length();}
It works fine.
Question:
I don't understand what is wrong with the function without the &, and how does it fix the problem?
The difference lies in which object owns the data that cstr points to.
string str5="abcdefg";
test_class test;
test.SetStr(str5);
cout<<test.cstr<<endl;
When you pass by reference, SetStr retrieves the pointer directly from str5 - str5 owns the data and the pointer remains valid for as long as str5 exists.
Since str5 still exists when you print test.cstr, everything is fine.
When you pass by value, the data is owned by the parameter, which is a copy of str5.
Since the parameter object is destroyed when the function returns, the pointer to its data is invalid afterwards, and dereferencing it is undefined.