This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
In C, why is the asterisk before the variable name, rather than after the type?
Declaring pointers; asterisk on the left or right of the space between the type and name?
I have been using pointers for a while and used to declare pointers like
int *x;
But noticed thru some code that, the * seems to be after data type in some cases, like
void* setValue(){
/* */
}
What's the difference and why it's used like that
Semantically nothing. It is style.
The advantage for putting the star right next to the variable is preventing this common error:
char* str1, str2;
/* str2 is a char, not char* ! */
char *str1, *str2;
/* ok */
This issue is non-existent with return types, so it matters even less there.
It's exactly the same as the difference between a+b and a + b - that is, there is no difference. Whitespace has no meaning at all, except when it's needed to separate tokens.
no difference, in some cases its better to keep it to the right:
int* p1,p2;
looks like p1 and p2 ara pointers, while only p1 is,
int *p1,p2;
now it looks a bit better, but good style is to split it to separate lines:
int *p1;
int p2;
No semantic difference.
Usually it is recommended to keep the * next to the type because the real type of x is void *. However this is syntactically false, since C/C++ binds the star to the variable name.
int *x, y; // declare one pointer to int x and one int y
Personally I try to keep the * in the middle
int * x;
A pointer to void, noted as void* is a generic opaque pointer. You can pass it (as argument, result, thru variables, fields...) and compare it but the only way to get the pointed data is to cast it appropriately. An inappropriate cast is undefined behavior and can crash your program.
As for the space before or after the * denoting pointers in types, it is a style thing. Spaces are not really significant, except as token separator (and * is a token by itself).
I strongly suggest to be consistent with spacings. You could use tools like e.g. indent to indent your source code (and passing -T options to it help good indentation of type names). The GNU indent tool is normalizing spaces and has many options to tune its behavior (you might put them in a .indent.pro file). For C++ code, consider using astyle instead of indent.
Related
I am new to C++ and trying to convert string into integer. I was using atoi but there are some restrictions so I start using strtol which works perfectly. However, I would like to learn more on *temp and &temp (I have google and learn that it is a temporary space for storage) but would like to learn the difference and when to use which.
char *temp;
int m = strtol (argv[1],&temp,10);
if (*temp != '\0')
*temp is a pointer to a variable named temp and &temp takes the address of that variable
First of all jessycaaaa welcome to Stackoverflow.
I am new to C++ and trying to convert string into integer.
For me this looks like plain C-code. You can compile this with a C++ compiler though.
I was using atoi but there are some restrictions so I start using strtol which works perfectly.
Since you get an undefined behavior using atoi when argv[1] contains something different than a number, strtol is an approach to go for. If you share us a bit more code, we would help you better on your questions.
However, I would like to learn more on *temp and &temp (I have google and learn that it is a temporary space for storage) but would like to learn the difference and when to use which.
First of all you have to distinguish between use and declaration
char *temp;
Here you declare (*-symbol in declaration) a pointer named temp of type char. A pointer is a variable which stores the memory address (where it is pointing to). Here you did not define an address so it most likely will point a random space, but then
int m = strtol (argv[1],&temp,10);
you pass the address of the pointer (&-symbol, use-case, address-of operator) to strtol, so you get an address pointing to the part of the argv[1] where the number literals end, that is all fine. The function also returns the numerical value of the read string as long and is converted to an int.
if (*temp != '\0')
Here you access the value of what the address is pointing to (*-symbol, use-case, dereference operator). \0 is normally set as indication for a null-terminated string. So you are asking if the previously read end part has the null-termination character.
You know what: in C++ there are more elegant ways to accomplish that using stringstreams:
std::stringstream
Just an idea if you don't want to handle too much string manipulation in C and annoyances with pointers.
Also I would read a good book about C (not C++). C++ has also the references don't get confused by those. If you dominate the pointer-concept of C, I'm pretty sure everything else will be very clear for you.
Best regards
* and & are one of the first hurdles that programmers new to C and C++ have to take.
To really understand these concepts, it helps to know a bit more about how memory works in these languages.
First of all: C++ is just C but with classes and many other additional features. Almost all C programs are valid C++ programs. C++ even started out as a language that was compiled to C first.
Memory is, roughly speaking, divided in two parts, a 'stack' and a 'heap'. There are also other places for the code itself and compile-time constants (and maybe a few more) et cetera but that doesn't matter for now. Variables declared within a function always live on the stack. Let's see this in action with a simple example and analyse how memory is organized to build a mental model.
#include <iostream>
void MyFunction() {
int intOnStack = 5;
int* intPtrOnStack = new int(6); // This int pointer points to an int on the heap
std::cout << intOnStack << *intPtrOnStack;
delete intPtrOnStack;
}
int main() { MyFunction(); }
This program prints 56 when executed. So what happens when MyFunction() gets called? First, a part of the stack is reserved for this function to work with. When the variable intOnStack is declared within the function, it is placed in this part of the stack and it is initialized with (filled with) the int value 5.
Next, the variable intPtrOnStack is declared. intPtrOnStack is of type int*. int*'s point to int's by containing their memory-address. So an int* is placed on the stack and it is initialized with the value that results from the expression new int(6). This expression creates a new int on the heap and returns the memory-address of this int (an int*) to it. So that means that intPtrOnStack now points to the int on the heap. Though the pointer itself lives on the stack.
The heap is a part of memory that is 'shared' by all functions and objects within the program. The stack isn't. Every function has its own part of the stack and when the function ends, its part of the stack is deallocated.
So int*'s are just memory-addresses of int's. It doesn't matter where the int lives. int*'s can also point to int's on the stack:
#include <iostream>
void MyFunction() {
int intOnStack = 5;
int* intPtrOnStack = &intOnStack; // This int pointer points to intOnStack
std::cout << intOnStack << *intPtrOnStack;
}
int main() { MyFunction(); }
This prints 55. In this example we also see the &-operator in action (there are several uses of & like the bit-wise-and, I'm not going into them).
& simply returns the memory-address (a pointer!) of its operand. In this case its operand is intOnStack so it returns its memory-address and assigns it to intPtrOnStack.
So far, we've seen only int* as types of pointers but there exist pointer-types for each type of object that has a memory-address, including pointers. That means that a thing like int** exists and simply means 'pointer to a pointer to an int'. How would you get one? Like this: &intPtrOnStack.
Can pointers only live on the stack? No: new int*(&intPtrOnStack). Or new int*(new int(5)).
consider this code:
double *pi;
double j;
pi = &j;
pi[3] = 5;
I don't understand how is that possible that I can perform the last line here.
I set pi to the reference of j, which is a double variable, and not a double [] variable. so how is this possible that I can perform an array commands on it?
consider this code:
char *c = "abcdefg";
std::cout << &(c[3]) << endl;
the output is "defg". I expected that I will get a reference output because I used &, but instead I got the value of the char * from the cell position to the end. why is that?
You have two separate questions here.
A pointer is sometimes used to point to an array or buffer in memory. Therefore it supports the [] syntax. In this case, using pi[x] where x is not 0 is invalid as you are not pointing to an array or buffer.
Streams have an overload for char pointers to treat them as a C-style string, and not output their address. That is what is happening in your second case. Try std::cout << static_cast<const void *>(&(c[3])) << endl;
Pointers and arrays go hand in hand in C (sort of...)
pi[3] is the same as *(pi + 3). In your code however this leads to Undefined Behavior as you create a pointer outside an object bounds.
Also be careful as * and & are different operators depending on in which kind of expression the appear.
That is undefined behavior. C++ allows you to do things you ought not to.
There are special rules for char*, because it is often used as the beginning of a string. If pass a char* to cout, it will print whatever that points to as characters, and stop when it reaches a '\0'.
Ok, so a few main things here:
A pointer is what it is, it points to a location in the memory. So therefore, a pointer can be an array if you whish.
If you are working with pointers (dangerous at times), this complicates things. You are writing on p, which is a pointer to a memory location. So, even though you have not allocated the memory, you can access the memory as an array and write it. But this gives us the question you are asking. How can this be? well, the simple answer is that you are accessing a zone of memory where the variable you have created has absolutely no control, so you could possibly be stepping on another variable (if you have others) or simply just writting on memory that has not been used yet.
I dont't understand what you are asking in the second question, maybe you could explain a little more? Thanks.
The last line of this code...
double *pi;
double j;
pi = &j;
pi[3] = 5;
... is the syntactic equivalent to (pi + 3) = 5. There is no difference in how a compiler views a double[] variable and a double variable.
Although the above code will compile, it will cause a memory error. Here is safe code that illustrates the same concepts...
double *pi = new double[5]; // allocate 5 places of int in heap
double j;
pi[3] = 5; // give 4th place a value of 5
delete pi; // erase allocated memory
pi = &j; // now get pi to point to a different memory location
I don't understand how is that possible that I can perform the last
line here. I set pi to the reference of j
Actually, you're setting your pointer pi, to point to the memory address of j.
When you do pi[3], you're using a non-array variable as an array. While valid c++, it is inherently dangerous. You run the risk of overwriting the memory of other variables, or even access memory outside your process, which will result in the operating system killing your program.
When that's said, pi[3] means you're saying "give me the slot third down from the memory location of pi". So you're not touching pi itself, but an offset.
If you want to use arrays, declare them as such:
double pi[5]; //This means 5 doubles arrayed aside each other, hence the term "array".
Appropos arrays, in c++ it's usually better to not use raw arrays, instead use vectors(there are other types of containers):
vector<double> container;
container.push(5.25); //"push" means you add a variable to the vector.
Unlike raw arrays, a container such as a vector, will keep it's size internally, so if you've put 5 doubles in it, you can call container.size(), which will return 5. Useful in for loops and the like.
About your second question, you're effectively returning a reference to a substring of your "abcdefg" string.
&([3]) means "give me a string, starting from the d". Since c-style strings(which is what char* is called) add an extra NULL at the end, any piece of code that takes these as arguments(such as cout) will keep reading memory until they stumble upon the NULL(aka a 0). The NULL terminates the string, meaning it marks the end of the data.
Appropos, c-style strings are the only datatype that behaves like an array, without actually being one. This also means they are dangerous. Personally I've never had any need to use one. I recommend using modern strings instead. These newer, c++ specific variables are both safe to use, as well as easier to use. Like vectors, they are containers, they keep track of their size, and they resize automatically. Observe:
string test = "abcdefg";
cout<<test.size()<<endl;//prints 7, the number of characters in the array.
test.append("hijklmno");//appends the string, AND updates the size, so subsequent calls will now return 15.
i am stuck and unable to figure out why this is the following piece of code is not running .I am fairly new to c/c++.
#include <iostream>
int main(){
const char *arr="Hello";
const char * arr1="World";
char **arr2=NULL;
arr2[0]=arr;
arr2[1]=arr1;
for (int i=0;i<=1;i++){
std::cout<<arr2[i]<<std::endl;
}
return 0;
}
where as this is running perfectly fine
#include <iostream>
int main(){
const char *arr="Hello";
const char * arr1="World";
char *arr2[1];
arr2[0]=arr;
arr2[1]=arr1;
for (int i=0;i<=1;i++){
std::cout<<arr2[i]<<std::endl;
}
return 0;
}
Why is this? and generally how to iterate over a char **?
Thank You
char *arr2[1]; is an array with one element (allocated on the stack) of type "pointer to char". arr2[0] is the first element in that array. arr2[1] is undefined.
char **arr2=NULL; is a pointer to "pointer to char". Note that no memory is allocated on the stack. arr2[0] is undefined.
Bottom line, neither of your versions is correct. That the second variant is "running perfectly fine" is just a reminder that buggy code can appear to run correctly, until negligent programming really bites you later on and makes you waste hours and days in debugging because you trashed the stack.
Edit: Further "offenses" in the code:
String literals are of type char const *, and don't you forget the const.
It is common (and recommended) practice to indent the code of a function.
It is (IMHO) good practice to add spaces in various places to increase readability (e.g. post (, pre ), pre and post binary operators, post ; in the for statement etc.). Tastes differ, and there is a vocal faction that actually encourages leaving out spaces wherever possible, but you didn't even do that consistently - and consistency is universially recommended. Try code reformatters like astyle and see what they can do for readability.
This is not correct because arr2 does not point to anything:
char **arr2=NULL;
arr2[0]=arr;
arr2[1]=arr1;
correct way:
char *arr2[2] = { NULL };
arr2[0]=arr;
arr2[1]=arr1;
This is also wrong, arr2 has size 1:
char *arr2[1];
arr2[0]=arr;
arr2[1]=arr1;
correct way is the same:
char *arr2[2] = { NULL };
arr2[0]=arr;
arr2[1]=arr1;
char **arr2=NULL;
Is a pointer to a pointer that points to NULL while
char *arr2[1];
is an array of pointers with already allocated space for two items.
In the second case of the pointer to a pointer you are are trying to write data in a memory location that does not exist while in the first place the compiler has already allocated two slots of memory for the array so you can assign values to the two elements.
If you think of it very simplistically, a C pointer is nothing but an integer variable, whose value is actually a memory address. So by defining char *x = NULL you are actually defining a integer variable with value NULL (i.e zero). Now suppose you write something like *x = 5; This means go to the memory address that is stored inside x (NULL) and write 5 in it. Since there is no memory slot with address 0, the the entire statement fails.
To be honest it;s been ages since I last had to deal with such stuff however this little tutorial here, might clear the motions of array and pointers in C++.
Put simply the declaration of a pointer does NOT reserve any memory, where as the declration of a array doesn't.
In your first example
Your line char **arr2=NULL declares a pointer to a pointer of characters but does not set it to any value - thus it is initiated pointing to the zero byte (NULL==0). When you say arr2[0]=something you are attempting to place a valuei nthis zero location which does not belong to you - thus the crash.
In your second example:
The declaration *arr2[2] does reserve space for two pointers and thus it works.
I have the following pointer.
char **x = NULL;
x is will point to an array of pointers. So is the following code correct?
x = new (nothrow) (*char)[20];
and we will dealocate it using
delete[] x;
Is
x = (char **) malloc(sizeof(char **) * 20);
and
x = new (nothrow) (*char)[20];
equivalent?
Apart from the pointer-syntax mentioned by unwind, it is equivalent: an array of 20 char* will be allocated and deleted in both cases.
C++-adept warning: use std::vector< std::string > instead :) No memory management needed.
No, that code has syntax errors. The asterisk goes after the type name, to form a pointer to that type. So it's:
char*
not:
*char
It's weird that you have this right in the "C-style" example using malloc(), but not in C++.
As many commenters have kindly enough pointed out, there are other issues with the malloc() and its use of sizeof, though. But at least it got the type name right. Personally I'm against repeating type names in malloc() calls if at all possible, so I would write that version like this, to allocate a dynamic array of 20 character pointers:
char **x;
x = malloc(20 * sizeof *x);
This way:
Should be read as "20 times the size of whatever x points at", i.e. 20 times the size of a single char * pointer.
Contains the magical constant 20 in one place only.
Doesn't repeat any part of the type, if you were to change to wchar_t **x this would still work, and not by chance.
Is written in C, since I felt that is more natural when discussing malloc(). In C++, you need to cast the return value. In C, you should never do that.
New was introduced in C++. Malloc is C.
You shouldnt mix and match them... i.e. dont use delete on something you have used malloc on. Check this article.
I'd question why you are allocating such a thing in the first place. In C++, a std::vector of std::string is much more likely to be what you need.
I'm building a comparator for an assignment, and I'm pulling my hair out because this seems to simple, but I can't figure it out.
This function is giving me trouble:
int compare(Word *a, Word *b)
{
string *aTerm = a->getString();
string *bTerm = b->getString();
return aTerm->compare(bTerm);
}
Word::getString returns a string*
Error:
In member function `virtual int CompWordByAlpha::compare(Word*, Word*)':
no matching function for call to...
...followed by a bunch of function definitions.
Any help?
You're comparing a string to a string pointer, and that's not valid. You want
return aTerm->compare(*bTerm);
You aren't getting the different uses of the * operator. The use of the * in "string* bTerm = b->getString()" means "bTerm is a pointer to a string". The use of the * inside of compare(*bTerm) means "take the value of the location pointed to by bTerm" instead of just using compare(bTerm) which simply attempts to compare the value of bTerm itself, which is a hex address.
This is also happening on the left side of that call:
aTerm->compare(*bTerm); //this statement
(*aTerm).compare(*bTerm); //is the same as this statement
The -> operator just reduces the amount of typing required.
P.S.: This kind of stuff you could have easily figured out from Google or your programming textbook. Although others may disagree, I don't feel that questions about completely basic syntax have any place on Stack Overflow.