TL;DR: Why do my char* variables have the same value, even though I input different ones?
Consider this very short program:
char *GetCompleteString ()
{
char *completeString;
std::cout << "Please enter the complete string.\n";
std::cin.getline(completeString,100);
return completeString;
}
char *GetSubstring ()
{
char* substring;
std::cout << "Please enter the substring for which to search.\n";
std::cin.getline(substring,100);
return substring;
}
//////////////////////////////////////////////////
int main(int argc, const char * argv[])
{
char *complete, *sub;
complete = GetCompleteString();
sub = GetSubstring();
//diagnostic
std::cout << "Complete is " << complete << " and sub is " << sub;
//diagnostic
return 0;
}
Now, I enter "foo" for the first string, and "bar" for the second. But the output tells me that both variables are the same.
The Xcode debugger shows that both variables have the same address, so when I assign a value to bar, the previously-entered foo (which lives at the same address) takes the same value. Here's what the debugger pane is showing just before the program exits:
argv const char ** 0x00007fff5fbff928
argc int 1
complete char * 0x00007fff5fbff928
*complete char 'b'
sub char * 0x00007fff5fbff928
*sub char 'b'
&complete char ** 0x00007fff5fbff8e8
&sub char ** 0x00007fff5fbff8e0
Why are these two variables being assigned the same address? What am I missing here? (And why are they retaining the same address as argv, which I think is just for interfacing with the CLI?)
And are they even retaining the same addresses? (I added the last two (&) lines to the debugger, myself. And those show different addresses...)
What you are doing there is undefined behaviour since neither completeString nor substring point to actual allocated memory. Anything can happen ;)
To be more precise: It is very likely that since you don't assign a value to the local variables they just get the first value lying on the stack which could be random or something the initialisation of your libc left there.
You can use following updated code
char *GetCompleteString ()
{
char *completeString = (char*)malloc(sizeof(char)*numberofchars);
std::cout << "Please enter the complete string.\n";
std::cin.getline(completeString,100);
return completeString;
}
char *GetSubstring ()
{
char* substring = (char*)malloc(sizeof(char)*numberofchars);
std::cout << "Please enter the substring for which to search.\n";
std::cin.getline(substring,100);
return substring;
}
//////////////////////////////////////////////////
int main(int argc, const char * argv[])
{
char *complete, *sub;
complete = GetCompleteString();
sub = GetSubstring();
//diagnostic
std::cout << "Complete is " << complete << " and sub is " << sub;
//diagnostic
return 0;
}
I have added memory allocation calls in your functions. numberofchars is numbers of chars you expect in that char *, or you can give some more thought to make it dynamic
There are a few problems with your code. I will list them here -
The statement char *completeString; defines completeString to be a pointer to a character. What you need is a character array to store the string entered by the user.
The variable completeString and subString are local to the functions GetCompleteString and GetSubstring respectively. They are allocated on the stack and go out of scope when the function returns. If you try to access them in main, then this invokes undefined behaviour. You need to allocate space to store strings on the heap using new operator. This allocates memory on the heap. You should free this memory using the delete[] operator after you are done with it.
The signature of main as per the standard should be one of the following -
int main(); or int main(int argc, char *argv[]);
Applying these changes to your code, it is
#include <iostream>
#define MAX_LEN 100
char *GetCompleteString()
{
char *completeString = new char[MAX_LEN];
std::cout << "Please enter the complete string.\n";
std::cin.getline(completeString, MAX_LEN);
return completeString;
}
char *GetSubstring()
{
char* substring = new char[MAX_LEN];
std::cout << "Please enter the substring for which to search.\n";
std::cin.getline(substring, MAX_LEN);
return substring;
}
int main()
{
char *complete, *sub;
complete = GetCompleteString();
sub = GetSubstring();
std::cout << "Complete is " << complete << " and sub is " << sub;
delete[] sub;
delete[] complete;
return 0;
}
Related
#include <iostream>
using namespace std;
int main() {
int age = 20;
const char* pDept = "electronics";
cout << age << " " << pDept;
}
The above code is normal.
Why shouldn't I use cout << *pDept instead of cout << pDept above?
Both of them are legal in C++. Which one to use depends on what you want to print.
In your case, pDept is a pointer that points to a char in memory. It also can be used as a char[] terminated with \0. So std::cout << pDept; prints the string the pointer is pointing to.
*pDept is the content that pDept points to, which is the first character of the string. So std::cout << *pDept; prints the first character only.
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;
}
This is not so much a question that I need solving, it's more a case of I made a mistake which resulted in weird output, and I'm curious what's going on.
So if point1 is a pointer to the char "var", and point2 is a pointer to the pointer point1, to correctly dereference point2 as follows:
cout << **point2 << endl;
Which would ouput "y" as expected.
However, if I incorrectly dereference the pointer, as follows:
cout << *point2 << endl;
Then the output would include any subsequent variables declared after the initial variable var.
For example, in the code below, var2 would also be included, for an ouput of "yn", and further variables such as
char var3 = 'a';
char var4 = 'b';
Also seem to be included for an ouput of "ynab".
I think I understand how it's happening, and outputting the memory addresses of each of the variables through a method such as:
cout << (void *) &var <<endl;
Which confirms that each variable is adjacent in memory, however I'm unsure why it is happening.
Why does improperly dereferencing a pointer to a pointer seem to return successive variables?
Code:
#include <stdio.h>
#include <iostream>
using namespace std;
char var = 'y';
char var2 = 'n';
//Declare point1 as a pointer to a char
char* point1 = &var;
//Declare point2 as pointer to pointer to char
char** point2 = &point1;
int main(int argc, char **argv)
{
cout << "Dereference point1: " << *point1 << endl;
cout << "Dereference point2: " << **point2 << endl;
cout << "Bad dereference of point2: " << *point2 << endl;
cout << "Var: " << var << endl;
return 0;
}
The expression *point2 is of type char * which is treated as a string. If it's not really a string then you have undefined behavior and that's really the end of the story.
In reality what happens is that the output operator << reads consecutive bytes from memory until it hits a zero (the "string terminator"). In your case the compiler have put the storage for the variables next to each other, that's why you see both being output in the "string".
C++ thinks that the pointer to char is the beginning of a string. So it tries to continue printing until it finds a NULL value.
Hello I am trying to read some arguments and process them but when i try to read arguments via if else ladder a problem occurs
int main (int argc, char *argv[])
{
cout << argv[1] << endl;
if (argv[1] == "process")
cout << "yes" << endl;
else
cout << "no" << endl;
}
This code outputs:
process
no
Do you know why the output is no instead of yes?
By the way I tried to convert either one of them to a string and compared it with another surprisingly it worked, even though I couldn't figure out why.
argv[1] is a pointer, actually a char * (see the definition char *argv[]), and in your code "process" (which is a const char []) also decays to a const char *, so you are basically comparing two char *.
Since char * are simply pointers, then you are comparing addresses, not "string", and obviously argv[1] and "process" are not stored at the same address.
If you convert one of the two to std::string, then you are comparing a std::string and char * (or const char *), and std::string has an overloaded operator== for char * so it works.
You could compare "C strings" (aka char arrays) using strcmp or strncmp.
argv[1] == "process" compares pointers. Use strcmpto compare the strings behind the pointers:
#include <string.h>
int main (int argc, char *argv[])
{
cout << argv[1] << endl;
if (strcmp(argv[1],"process")==0)
cout << "yes" << endl;
else
cout << "no" << endl;
}
When I run the following code:
int i[] = {1,2,3};
int* pointer = i;
cout << i << endl;
char c[] = {'a','b','c','\0'};
char* ptr = c;
cout << ptr << endl;
I get this output:
0x28ff1c
abc
Why does the int pointer return the address while the char pointer returns the actual content of the array?
This is due to overload of << operator. For char * it interprets it as null terminated C string. For int pointer, you just get the address.
The operator
cout <<
is overload 'char *' so it knows how to handle it (in this case, printing all chars till the end one).
But for int is not, so it just prints out the 'memory address'
A pointer to char is the same type as a string literal. So for the sake of simplicity, cout will print the content of the char array as if it was a string. So when you are doing this:
cout << "Some text" << endl;
It does not print the address, the same way as your code is doing.
If you want to pring the address, cast it to size_t
cout << reinterpret_cast<size_t>(ptr) << endl;