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.
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)).
static void (* __set_malloc_handler(void (*__f)()))();
I think __set_malloc_handler is a function pointer, and it points to a function which also needs a function pointer. But, I have no idea how to understand the whole statement. How does it work?
It's easier to understand with some aliasing.
//pointer to function taking no arguments and void return
typedef void(*function_pointer)();
//function taking "function_pointer" and returning "function_pointer"
function_pointer __set_malloc_handler(function_pointer __f);
To read something like that, I recommend the right-left rule. It's what I always use. There's also a spiral rule, but I get annoyed when it doesn't form a perfect spiral and I get too distracted by that to focus. You probably won't have that issue.
The explanation on either page is more thorough, but here's a crash course.
Essentially, read these symbols as:
* = "pointer to"
(...) = "function taking ..."
[...] = "array of size ..."
Read to the right until you find a ) that didn't have a matching ( yet. Then read to the left until you find a ( to match it. Start reading right again. If you hit the end of the line on the right, you finish reading to the left.
To the immediate right of the identifier __set_malloc_handler is an open parenthetical (, meaning it is a function. Everything from that to the matching ) is the parameter type. I'd recommend ignoring it at first and coming back to it later. Step by step:
__set_malloc_handler(...) //function taking ...
(*__set_malloc_handler(...)) //and returning a pointer
(*__set_malloc_handler(...))() //to a function taking no arguments
void (*__set_malloc_handler(...))() //that returns void
Looking at the parameter, we have:
(*__f) //pointer
(*__f)() //to function taking no arguments
void (*__f)() //and returning void
__set_malloc_handler is a function that takes a "function pointer to a void function" and returns a "function pointer to a void function". Keyword static makes it only visible to the current file.
I'm having a hard time figuring out why the initialisation at NULL of one pointer is bugging my program.
In order to not receive a compilation error, almost all the pointers in my code need to be initialise as nullptr like usual. Problem is, when I tried to use them afterwards, I get a whole bunch of errors telling me the null pointer is invalid. To overcome this error, the buggy pointers are now declare as an array. This way all my problems with this initialisation are gone. Everything seems to work fine until I realise one of my conditional branch was always returning false.
The full code is a bit too long and some parts use french words, so let's just paste what interest us...
struct Numero {
int num;
char client[50];
Message *listeMessage = nullptr;
Numero *suivant = nullptr;
int nbmsg = 0;
};
char buff_char[50];
number = new Numero;
file >> number->client; // getting the right char client[50] from the file
if (number->client == buff_char)
break;
I also tried if(*number->client == *buff_char) without success. I'm now thinking that the problem is probably the array of char, but because of my previous problem I can't really change that so I'm hoping somebody can figure out what's going on here.
Note: Don't suggest anything related to strings, I can't use them because it's part of the challenge here to practice with pointers.
number->client == buff_char
Both of these are arrays, which decay into pointers. They are two different arrays with two different addresses, so this will always return false.
*number->client == *buff_char
This would compare the first element in each array, which is also not what you want.
You can use a standard library function like strcmp.
If you can't use the standard library, loop over each array until one has a different element than the other (not equal), they both have '\0' (equal), or they both reach 50 (equal).
In If do a comparison instead of assignment
if (number->client == buff_char)
In C++ = is the assignment operator. You want == for equality. What your if statement does right now is sets client equal to buff_char and then evaluates based on the newly assigned value of client.
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.
CARD& STACK::peek()
{
if(cards.size == 0)
{
CARD temp = CARD {-1, -1};
return temp;
}
return cards.back();
}
This is the function I am having trouble with.
CARD is just a struct with two int variables, called rank and suit.
STACK is a class that manages an std::vector<CARD>, that is called cards.
The function is supposed to return a reference to the card on top of the stack, or return the reference to a dummy card if the vector is empty.
First of all, I get a warning that says a reference to a local variable temp is returned. What is wrong with that? How will that effect the function? What do I do about it?
Second, I am trying to use this function with another function I created called cardToString
char* cardToString(CARD& c);
It is supposed to use the rank and suit variables in the passed CARD to look up string values in a table, concatenate the two strings together, and return a pointer to the new string.
So the end result looks like:
cout<<cardToString(deck.peek())<<"\n";
but this line of code will execute up to the cardToString function, then just stop for some reason. It is annoying the hell out of me because it just stops, there is no error message and there does not look like there is anything wrong to me.
Can somebody help me out?
Edit: here is the cardToString function
char *cardToString(const CARD& c)
{
if(c.r >= 13 || c.r < 0 || c.s >= 4 || c.s < 0)
{
std::cout<<"returned null";
return NULL;
}
char *buffer = new char[32];
strcpy(buffer, RANKS[c.r]);
strcat(buffer, " of ");
return strcat(buffer, SUITS[c.s]);
}
I specifically want the function STACK.peek() to return the address of the CARD that already exists on the top of the STACK. It seems to make more sense to do that than to create a copy of the card that I want to return.
First of all, I get a warning that says a reference to a local variable temp is returned. What is wrong with that? How will that effect the function? What do i do about it?
A local variable, as it name implies, is local to the function it belongs to, so it's destroyed as the function returns; if you try to return a reference to it, you'll return a reference to something that will cease to exist at the very moment the function returns.
Although in some cases this may seem to work anyway, you're just being lucky because the stack hasn't been overwritten, just call some other function and you'll notice it will stop working.
You have two choices: first of all, you can return the CARD by value instead of reference; this, however, has the drawback of not allowing the caller to use the reference to modify the CARD as is stored in the vector (this may or may not be desirable).
Another approach is to have a static dummy CARD instance stored in the STACK class, that won't have these lifetime problems, and that can be returned when you don't have elements in the vector; however, you should find a method to "protect" its field, otherwise a "stupid" caller may change the values of your "singleton" dummy element, screwing up the logic of the class. A possibility is to change CARD in a class that will encapsulate its fields, and will deny write access to them if it's the dummy element.
As for the cardToString function, you're probably doing something wrong with the strings (and I'm almost sure you're trying to return a local also in this case), but without seeing the body of the function it's difficult to tell what.
By the way, to avoid many problems with strings I suggest you to use, instead of char *, the std::string class, which takes away most of the ugliness and of the low level memory management of the usual char *.
Also, I'd suggest you to change cardToString to take a const reference, because most probably it doesn't need to change the object passed as reference, and it's good practice to clearly mark this fact (the compiler will warn you if you try to change such reference).
Edit
The cardToString function should be working fine, as long as the RANKS and SUITS arrays are ok. But, if you used that function like you wrote, you're leaking memory, since for each call to cardToString you make an allocation with new that is never freed with delete; thus, you are losing 32 bytes of memory per call.
As stated before, my tip is to just use std::string and forget about these problems; your function becomes as simple as this:
std::string cardToString(const CARD& c)
{
if(c.r >= 13 || c.r < 0 || c.s >= 4 || c.s < 0)
return "(invalid card)";
return std::string(RANKS[c.r]) + " of " + SUITS[c.s];
}
And you don't need to worry about memory leaks and memory allocations anymore.
For the reference/value thing: if the caller do not need to use the reference to modify the object stored in the vector, I strongly suggest passing it by value. The performance hit is negligible: two ints instead of one pointer means 8 vs 4 bytes on most 32 bit architectures, and 8 bytes vs 8 bytes on most 64 bit machines (and also accessing the fields via pointer has a small cost).
This kind of micro-optimization should be the last of your concerns. Your top priority is to write correct and working code, and the last thing you should do is to let micro-optimization get in the way of this aim.
Then, if you experience performance problems, you'll profile your application to find where the bottlenecks are and optimize those critical points.
You cannot return a reference to a local variable, because the local variable no longer exists when the function returns.
You need to return by-value, not by-reference (i.e. CARD STACK::peek() { ... }).