1
\$\begingroup\$

I think this question should have been posted on Stack Overflow, but as I am using all of this stuff to make a video game, I decided to post it here.

So, suppose you have an integer value called 'firstgid' declared:

int firstgid;

And I'm not telling the program what value firstgid equals to, like I'm not saying that int firstgid = 5; or something.

And then somewhere else in the program, I say:

SDL_Texture* tex(graphics, &firstgid);

Notice the &firstgid here. I am not telling the program what firstgid is, and still I am making a reference to it using the ampersand (&) symbol.

So, if I do that, will the program crash and display this breakpoint error on the output screen?:

Unhandled exception thrown. Read access violation:
  **this** was nullptr

A good folk just told me that the **this** was nullptr breakpoint error is triggered when we are calling a function on an unknown value or stuff.

What do you guys think about it? Thank you for your kind assistance.

\$\endgroup\$
  • \$\begingroup\$ Not sure if this is game related but just your usual stackoverflow question. \$\endgroup\$ – Sidar Sep 24 '17 at 5:19
  • \$\begingroup\$ This does really belong on stackoverflow, not here. That being said, what does the "tex" function do? What you did isn't technically illegal in C++, but may cause something inside of tex to suffer an exception like this. It's also possible that you failed to initialize a library. \$\endgroup\$ – Cort Ammon Sep 24 '17 at 6:29
  • \$\begingroup\$ @CortAmmon. Don't worry about tex. It's not a function, it's a variable. What I mean is-- I am doing a pointer reference to firstgid in this statement. Please help. Thank you. \$\endgroup\$ – Aditya Chandra Sep 24 '17 at 6:46
  • \$\begingroup\$ @Aditya Chandra could you please explain how is tex a variable? \$\endgroup\$ – jjimenezg93 Sep 24 '17 at 7:37
  • \$\begingroup\$ @CortAmmon SDL_Texture is a function that is defining a variable called 'tex', for further functionality, using the asterisk (*). \$\endgroup\$ – Aditya Chandra Sep 24 '17 at 8:43
2
\$\begingroup\$

In C++, pointers are a very important concept. In this case, they get a bit confusing because they're pointing to an unspecified integer, so let's get the rules about unspecified values out of the way.

The specific line from the specification is section 8.5.11:

If no initializer is specified for an object, the object is default-initialized; if no initialization is performed, an object with automatic or dynamic storage duration has indeterminate value.

What that last bit means is that your integer, firstgid, has an unspecified value because you did not assign one. It might be 0. It might be 1. It might be -1195716. It might even be different each time you run the program. It is legal to access this value, it's just not specified what its value will be. If it were a pointer, it would be a pointer to an unspecified memory address, so dereferencing it would be illegal, but firstgid is not a pointer, it's an int.

A key thing to note is that you can always assign a value to a variable that previously had an unspecified value. If you were to later write firstgid = 1, that would be completely valid and firstgid would have a defined value from that point on (it's value would be 1).

Now for the pointers. The & operator is known as the "address of" operator. It takes any variable and returns the address of that variable as a pointer. In your case, because firstgid is an int, &firstgid will be an int*. The value of this pointer (the address) is defined, even if the value of the integer it is pointing at is not. The important thing here is that the pointer is valid, and we can dereference it. For example:

int firstgid; // an int with an unspecified value
int* ptr = &firstgid; // a pointer with a specified value (pointing at firstgid)

int temp1 = *ptr; // dereferencing the pointer to an unspecified value is valid,
                 // but the value of temp itself is unspecified
*ptr = 1; // assigning a value to the int that ptr points to
int temp2 = firstgid; // temp2 is now 1

So, in this case, you can pass &firstgid to tex(), as long as tex() operates correctly if the pointer is a pointer to an unspecified value.

The specific error you mention is what happens when you try to call a method on an object that you got by derefereincing a null pointer:

MyObject* objPtr = nullptr; // create a new pointer, not pointing at anything
objPtr->foo(); // ERROR!  **this** was nullptr

The difference between your first case and this second one is that, in the first case, you had a perfectly valid pointer, it was just pointing to an object with an unspecified value. In the second case, we're actually calling a member function from a null pointer. Pointers must be pointing at a valid object if you want to use them to call member functions on the object they point at. However, this is fine:

MyObject* objPtr = nullptr;
someFunction(objPtr);

In this case, all we did was pass a null pointer to someFunction, which is legal, as long as someFunction is ready for it. For example, it might have some code like:

void someFunction(MyObject* obj)
{
    // If the user does not provide an object, use the default one
    if (obj == nullptr)
        obj = sDefaultObject;
    ...
}

In this case, objPtr will not change (because the pointer to the object was copied as part of the function call), but clearly someFunction will operate on some other object.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thank you, Ammon. This answer will not only aid me now, it will be helpful in the future as well. \$\endgroup\$ – Aditya Chandra Sep 24 '17 at 16:05
2
\$\begingroup\$

As long as you don't access/use firstgid before initializing it, there's no problem at all with that. Check if the function which is receiving a reference to it is not using it.

By using it I mean calling a function on the object, using its value (which is not necessarily bad, the only problem is that you don't know what value it holds) or trying to dereference it if it were a pointer.

| improve this answer | |
\$\endgroup\$
  • 2
    \$\begingroup\$ +1, good answer, but I just wanted to quickly add that it's okay to assign to the integer inside the function: *firstgid = 42;, since it's actually reserved space and not equal to nullptr. \$\endgroup\$ – Tyyppi_77 Sep 24 '17 at 8:42
  • \$\begingroup\$ @Tyyppi_73 : Hi, Tyyppi_73. The 'good folk' I talked about in my question is you. \$\endgroup\$ – Aditya Chandra Sep 24 '17 at 9:20
  • \$\begingroup\$ @Tyyppi_73 : Can we tell the program what the value of 'firstgid' is inside a function using '*'? \$\endgroup\$ – Aditya Chandra Sep 24 '17 at 9:23
  • 1
    \$\begingroup\$ Yes, that will change the value of the integer outside of the function call too. That's how multiple return values are sometimes implemented, using pointers. \$\endgroup\$ – Tyyppi_77 Sep 24 '17 at 9:47
  • \$\begingroup\$ You can't change the value of a non-pointer variable using *. It will give you a dereferencing error. If you want to assign it you must use firstgid = value \$\endgroup\$ – jjimenezg93 Sep 24 '17 at 9:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.