Value returned changes original passed value - c++

So I am writing a main function that passes two char values into five different char* functions one by one, but when I return the value of it, it completely changes my value; how would I fix this?
For example:
Passing char one into my function, myStrCat, returns world! since that is what my function does (btw, the assignment is how to code specific library functions without any library imports). But not only does it return it, it changes it. So when I pass one into the next function down, it will return the wrong value as one (Hello ) isn't being passed, instead two (World!) is.
char one[size] = "Hello ";
char two[size] = "World!";
cout << "strlen: " << myStrLen(one) << endl;
cout << "strcat: " << myStrCat(one, two) << endl;
Word function is being passed into
char* myStrCat(char inputOne[], char inputTwo[]){
int sizeOne = myStrLen(inputOne);
int sizeTwo = myStrLen(inputTwo);
for(int i = 0; i < sizeTwo; i++){
inputOne[i + sizeOne] = inputTwo[i];
}
return inputOne;
}

Related

Providing initial text for the readline buffer

In a readline buffer I want to provide an initial value the user can edit. This can either be a default value or the old value of the field already saved to my database. The entered value shall not be added to the readline-history as it is only "data" not a command.
From the samples here and on the internet I have learned that this code should do the job:
char *deftext;
int MatCustom::set_deftext ()
{
// cout << "set_deftext called ... deftext: " << deftext << endl;
if (deftext)
{
// cout << "inserting..." << endl;
rl_insert_text(deftext);
// rl_line_buffer = deftext;
// cout << rl_stuff_char('J') << endl;
rl_redisplay();
deftext = (char *)NULL;
rl_startup_hook = (rl_hook_func_t *)NULL;
// rl_pre_input_hook = (rl_hook_func_t *)NULL;
};
return 0;
}
string MatCustom::getlineWithoutHistory(const string &field) {
string returnString;
const char *buffer;
char *cstr = new char[field.length() + 1];
strcpy(cstr, field.c_str());
deftext = cstr;
// cout << "Deftext in getLineWithoutHistory: " << deftext << endl;
rl_startup_hook = set_deftext;
// rl_pre_input_hook = set_deftext;
buffer = :: readline("");
if (buffer != nullptr) {
returnString = buffer;
} else {
returnString = "";
}
free((void *) buffer);
delete [] cstr;
return returnString;
}
It works perfectly well to convert my old value to a char* and pass it to the global variable deftext, because a parameter cannot be given to the readline-hook-functions.
I am experiencing problems: Whenever I use the rl_startup_hook, which is said to be called before the prompt gets printed, I find this this hook never gets executed. However, when I use the rl_pre_input_hook, which is called prior to the input to begin, my function set_deftext actually gets called. This functions finds deftext set.
Still, I don't get any text inserted into the input buffer. The function rl_insert_text produces no change – even when I use rl_redisplay(). Directly changing the buffer with rl_line_buffer = deftext; also has no effect. When I try cout << rl_stuff_char('J') << endl; for debugging just to insert a single char, nothing happens and the function returns 0 indicating an unsuccessful insert.
Both functions are static member functions. I usually call my function with
input = MatCustom::getlineWithoutHistory(rawValue);
to edit to provided value (rawValue).

Visual Studio C++ access violation when modifying a pointer passed into a function

I want to implement a simple function that gets a string as a char pointer and modifies the string in a function. The requested function must be void then I have to modify the primary string passed into my function. I got an access violation error and googled it but nothing helped.
My sample code is here:
#include "iostream"
using namespace std;
void FindCommonStr(char*& Common,int &A)
{
int i=0;
while(1)
{
if(Common[i]=='\0')
break;
i++;
}
cout<<"Number of Elements = "<<i<<endl;
for (int j=0 ; j<i-1;j++)
Common[j]='y';
A=2;
}
void main()
{
int A=0;
char* Common = new char;
Common = "Hello World!";
cout<<"Common0 = "<< Common<<endl;
cout<<"A0 = "<< A<<endl;
FindCommonStr(Common,A);
cout<<"Common1 = "<< Common<<endl;
cout<<"A1 = "<< A<<endl;
}
Actually the problem occured in this part of FindCommonStr funtion:
for (int j=0 ; j<i-1;j++)
Common[j]='y';
If I comment this part everything works but I cannot change the string values. I also tested the pointer to pointer solution by defining the function as:
FindCommonStr(char **Common,...
It doesn't help though and I got the violation error again.
Is it even possible to do such a thing?
When you do this:
Common = "Hello World!";
you are making the pointer Common point at a literal C-style string (and incidentally leaking the original char that you allocated via new previously). It is not valid to try to modify such a literal, so when you pass this to FindCommonStr and try to modify it you get an access violation.
You should avoid using C-style strings and use proper C++ std::string instead - this will save a lot of problems and is much more robust, as well as being more appropriate for C++ programming.
Fixed version of your code:
#include <iostream>
#include <string>
using namespace std;
static void FindCommonStr(string &Common, int &A)
{
int i = 0;
while (1)
{
if (Common[i] == '\0')
break;
i++;
}
cout << "Number of Elements = " << i << endl;
for (int j = 0; j < i - 1; j++)
Common[j] = 'y';
A = 2;
}
int main()
{
int A = 0;
string Common = "Hello World!";
cout << "Common0 = " << Common << endl;
cout << "A0 = " << A << endl;
FindCommonStr(Common, A);
cout << "Common1 = " << Common<<endl;
cout << "A1 = " << A << endl;
return 0;
}
Alternatively if this is a homework assignment where you are required to use C strings for some unfathomable reason then a fixed version using only char * strings might look like this:
#include <iostream>
using namespace std;
static void FindCommonStr(char *Common, int &A)
{
int i = 0;
while (1)
{
if (Common[i] == '\0')
break;
i++;
}
cout << "Number of Elements = " << i << endl;
for (int j = 0; j < i - 1; j++)
Common[j] = 'y';
A = 2;
}
int main()
{
int A = 0;
char Common[] = "Hello World!";
cout << "Common0 = " << Common << endl;
cout << "A0 = " << A << endl;
FindCommonStr(Common, A);
cout << "Common1 = " << Common<<endl;
cout << "A1 = " << A << endl;
return 0;
}
This part is conceptually wrong:
char* Common = new char;
// 'Common' is set to point to a piece of allocated memory
// (typically located in the heap)
Common = "Hello World!";
// 'Common' is set to point to a constant string
// (typically located in the code-section or in the data-section)
You are assigning variable Common twice, so obviously, the first assignment has no meaning.
It's like writing:
int i = 5;
i = 6;
On top of that, you "lose" the address of the allocated memory block, so you will not be able to release it at a later point in the execution of your program.
You seem to mixup char[] and string
When you write
char* Common = new char;
you allocate space on the heap for one character which Common is pointing to.
Then you write
Common = "Hello World!";
which sets the pointer Common to point to the string "Hello World" in read-only memory. The heap you allocated previously is now leaked.
There are basically two approaches:
Either you work with arrays of characters, in that case you write something like
char* Common = new char[strlen("Hello World!")+1];
strcpy(Common, "Hello World!");
Now common still points to the heap and the string has been copied there. The extra +1 byte is to hold the ending \0 string terminator.
You need to free the memory Common points to once you are done.
delete Common;
The other approach is to use the string template
std::string Common;
this allows you to assign a string, it capsules all the work with the heap array above.
Common = "Hello World!";
and there is no need to delete anything afterwards since std::string will do that for you.

Why doesn't the pointer for the char *str change when we reverse the string in this function?

I wrote a simple function to perform in place reversal:
void in_place_reverse(char *str){
if(!str || !(*str)){
return;
}
char *str_end = str+strlen(str)-1;
int temp;
while(str < str_end){
temp = *str;
*(str++) = *str_end;
*(str_end--) = temp;
}
}
I'm just wondering why when I do something like this:
char str[] = "Reverse me!";
cout << "Original: " << str << endl;
in_place_reverse(str);
cout << "Reversed: " << str << endl;
str wasn't changed inside of the function. The reason I ask is because the line *(str++) is incrementing the pointer that points to str. So what I'm really asking is why something like this isn't necessary:
char *str_beg = str;
char *str_end = str+strlen(str)-1;
int temp;
while(str_beg < str_end){
temp = *str_beg;
*(str_beg++) = *str_end;
*(str_end--) = temp;
}
So that we're not actually changing the pointer that points to the first position of str.
You actually are doing this implicitely because 'str' is passed by value (read: 'as a copy in a temporary variable').
To clarify this without the (distracting) pointer: consider
void increment(int x) {
x++;
}
int i = 1;
cout << i << endl;
increment(i);
cout << i << endl;
This will print '1' twice. The x that is seen inside the increment routine has the same value like the passed i. But it is not the same variable i. In fact it is a copy of i. When we return from the routine, the copy is discarded. Further reading: This would be different if we'd pass x by reference, like so:
void increment(int &x) {
x++;
}
The declaration of the function void in_place_reverse(char *str) results in a copy of the pointer being created when the function is called, in a variable called str that is private and local to the in_place_reverse. You can modify this value all you like without affecting the original that exists in the scope of the calling function.

What does this mean (C++): "warning: pointer to a function used in arithmetic [Wpointer-arith]"?

I am making a C++ program and I have a warning that keeps cropping up (I'm using g++):
warning: pointer to a function used in arithmetic [Wpointer-arith]
and I want to know: what exactly does this warning message mean? What is my compiler trying to tell me the problem is (in general terms) so I can better understand what I'm doing wrong?
Google searches turn up specific solutions to specific problems in people's code, but never tell me exactly what this warning message is trying to say.
I'm just learning arrays and I'm trying to make a program that prints "Hello, world!" one character at a time, each character being stored individually in an array and pumped to cout in a for loop.
Here is the code:
#include <iostream>
using namespace std;
int ARRAY_ELEMENTS = 14;
void greeting()
{
char greeting[ARRAY_ELEMENTS];
greeting[0] = 'H';
greeting[1] = 'e';
greeting[2] = 'l';
greeting[3] = 'l';
greeting[4] = 'o';
greeting[5] = ',';
greeting[6] = ' ';
greeting[7] = 'w';
greeting[8] = 'o';
greeting[9] = 'r';
greeting[10] = 'l';
greeting[11] = 'd';
greeting[12] = '!';
greeting[13] = '\0';
}
int main(int argc, char* argv[])
{
greeting();
for (ARRAY_ELEMENTS = 0;
ARRAY_ELEMENTS <= 13;
ARRAY_ELEMENTS++)
{
cout << greeting[ARRAY_ELEMENTS] << endl;
}
return 0;
}
Thank you for your time.
On this line:
cout << greeting[ARRAY_ELEMENTS] << endl;
you are referring to the function named greeting that you're treating as if it were an array.
greeting is a function, but you try to print it out like it's a char array. It doesn't help the clarity of your code that the function greeting() contains a char array by the same name - this is probably where you've gotten confused. If you give things distinct names, it would be more obvious what's going wrong.
You need to have your greeting() function return something, rather than just fill in a local array, which will not be accessible from outside of the function (and in any event will be discarded as soon as the function returns).
The statement greeting[ARRAY_ELEMENTS] doesn't do what you think it does.
From inside main the name greeting refers to the function void greeting(). You seem to be trying to print the char greeting[ARRAY_ELEMENTS] variable. But you cannot do that from main since that name is only visible from inside void greeting().
You should rename either the function or the variable to ensure that this confusion does not happen again, and beyond that you you have two options: Either ove the loop inside the function greeting or pass a pointer to a buffer into which the greeting must be set into the function. This might be a little more advanced than your current level but you will have to learn how to do it eventually, so no time like the present.
const int ARRAY_ELEMENTS = 14;
void make_greeting(char *greeting)
{
greeting[0] = 'H';
greeting[1] = 'e';
...
}
int main(int argc, char **argv)
{
char buffer[ARRAY_ELEMENTS];
make_greeting(buffer);
std::cout << "The greeting is \"" << buffer << "\"" << std::endl;
for(int i = 0; i != ARRAY_ELEMENTS; i++)
std::cout << "At position " << i << ": '" << buffer[i] << "'" << std::endl;
}
Of course, you should probably just be using std::string instead of character buffers anyways.
I think the problem here is that this code
greeting[ARRAY_ELEMENTS]
doesn't do what you think it does. This tries to index into position ARRAY_ELEMENTS of the function greeting, which isn't a function. The error you're getting is caused by the compiler thinking you're trying to treat greeting as an array, which isn't what you want to do.
There isn't a direct fix for this, but you could consider doing one of the following:
Change greeting to actually be an array.
Make greeting a function that takes in an index and produces the appropriate array value.
Hope this helps!

C++ references and references parameters

Please look at the code snippet below - I have declared 3 functions (i.e. 1 passing an int and the others passing reference to an int). After executing the program I found that the value of "count" variable after calling function (tripleByReference) has not been changed to reflect its triple (count is still equal to 5). However calling function (tripleByReferenceVoid) modifies the variable but this is due to the fact that changes occurred directly to the variable (count).
I understand that with pass by reference, the caller gives the called function the ability to access the caller's data directly and modify it but that could not be achieved by passing the variable to function (tripleByReference) - Please help me to understand this.
#include <iostream>
using namespace std;
/* function Prototypes */
int tripleByValue(int);
int tripleByReference(int &);
void tripleByReferenceVoid(int &);
int main(void)
{
int count = 5;
//call by value
cout << "Value of count before passing by value is: " << count << endl;
cout << "Passing " << count << " by value, output is: "
<< tripleByValue(count) << endl;
cout << "Value of count after passing by value is: " << count << endl;
//call by reference - using int tripleByReference
cout << "\n\nValue of count before passing by reference is: " << count << endl;
cout << "Passing " << count << " by reference, output is: "
<< tripleByReference(count) << endl;
cout << "Value of count after passing by reference is: " << count << endl;
//call by reference - using void tripleByReference
tripleByReferenceVoid(count);
cout << "\n\nValue of count after passing by reference is: " << count << endl;
cout << endl;
system("PAUSE");
return 0;
}//end main
int tripleByValue (int count) {
int result = count * count * count;
return result;
}//end tirpleByValue function
int tripleByReference(int &count) {
int result = count * count * count;
return result; //perform calcs
}//end tripleByReference function
void tripleByReferenceVoid(int &count) {
count *= count * count;
}//end tripleByReference function
Thank you.
tripleByReference doesn't change the value of count because you never assign to it. You are returning the value instead.
tripleByReferenceVoid is different. You are assigning to it (count *= ...) and that is why these changes are reflected.
In your function tripleByReference you are not even attempting to modify the value of count, while in your function tripleByReferenceVoid you are explicitly modifying count. Hence the obvious and expected effect: the latter function modifies count, the former doesn't. I.e. these functions do exactly what and only what you explicitly and consciously asked them to do.
Questions like this one is difficult to answer because it is virtually impossible to understand what made you to ask it. You seem to be puzzled by the fact that the behavior of these two functions is different. But why does it puzzle you, when you yourself explicitly wrote them to be different in that specific regard?