weak_ptr reset affects shared_ptr? - c++

I'm not very used to using weak_ptr and I'm facing a quite confusing situation. I'm using Intel XE 2019 Composer update 5 (package 2019.5.281) in combinaison with Visual Studio 2019 ver. 16.2.5. I compile in 64-bit. I use the standard C++ 17.
Here is the code for my spike solution:
#include <memory>
#include <iostream>
using namespace std;
int main( int argc, char* argv[] )
{
shared_ptr<int> sp = make_shared<int>( 42 );
cout << "*sp = " << *sp << endl;
weak_ptr<int> wp = sp;
cout << "*sp = " << *sp << ", *wp = " << *wp.lock() << endl;
wp.reset();
cout << "*sp = " << *sp << endl;
return 0;
}
The output I expected to have is:
*sp = 42
*sp = 42, *wp = 42
*sp = 42
...but here is what I obtained:
*sp = 42
*sp = 42, *wp = 42
*sp = -572662307
What is goin on? Is it normal for the shared_ptr to be modified/invalidated when the/an associated weak_ptr is reset? I'm a little confused about the results I obtained. To say the truth I didn't expect this result...
EDIT 1
While the bug occurs in 64-bit configuration, it doesn't in 32-bit. In this later configuration, the result is what is expected.
EDIT 2
The bug occurs only in Debug. When I build in Release, I get the expected result.

It appears it is a real bug on Intel ICC side; I have reported it.
Thanks again for helping me to pin-point this problem.

It looks like a bug in debug library, with sentinel values.It's easy to check, by using line I mentioned:
int i = 1; cout << i << " " << ++i << endl;
If output is 2 2 instead of 1 2, then compiler is not compliant and possibly still considers such case an UB. Sentinel values may be used erroneously in this case with call of reset(). Similar thing happens with deleting object created by placement new within preallocated static buffer, in debug mode it gets overwritten by some implementations with sentinel values.

Related

C++ program behaviour differs when compiled with Cygwin and MinGW

I am fairly new to C++ and have been tinkering with some simple programs to teach myself the basics. I remember a little while ago installing MinGW on my desktop (I think for the C compiler). I decided to go for Cygwin for C++ and it seems to have been working a treat, up until I noticed that it seems to behave differently from the MinGW compiler for this program. I'm probably breaking some coding golden rule, but the reason for this is that Windows CMD uses the MinGW compiler, or I can open the Cygwin shell and use that instead. Variety!
For the program below, I am making notes on the ternary operator and switch statement. I initialize 'a' and 'b', ask for user input, and then use a function to check which is larger.
I then ask for user input again, to over-write the values in 'a' and 'b' to something else. When compiling from Windows CMD, this works fine and I can overwrite with new input, and the #define MAXIMUM and MINIMUM functions work fine on the new values. When I compile on Cygwin, however, after the first 'pause', the program launches past the two std::cin's and just runs MAXIMUM and MINIMUM on the old values of 'a' and 'b'.
Obviously I have tried just creating two new int variables, 'c' and 'd', and then there is no issue. The values are not immutable in any sense that I am aware of (although I don't know much, so I could be wrong).
I wasn't sure if this was something to do with the auto keyword, so I specified the type as int manually.
I also checked the version of both compilers with 'g++ -v' in Cygwin and at the CMD.
#include <iostream>
#include <cstdlib>
#define MAXIMUM(a,b) ((a > b) ? a : b)
#define MINIMUM(a,b) ((a < b) ? a : b)
int ternary_op(int a, int b)
{
char x = 'a';
char y = 'b';
auto result_var = 0;
result_var = a > b ? x : y; //Shorthand if statement with syntax (test_condition) ? (if_true) : (if_false)
return result_var;
}
int main()
{
auto a = 0;
auto b = 0;
auto larger = 0;
auto smaller = 0;
std::cout << "Enter an integer: " << "\n";
std::cin >> a;
std::cout << "Enter another integer: " << "\n";
std::cin >> b;
char greater_var = ternary_op(a,b); //Therefore if condition a > b is satisfied, greater_var is assigned x ('a')
std::cout << greater_var << std::endl;
switch(greater_var){
case 'a':
std::cout << "First integer " << a << " is larger than second, " << b << std::endl;
break;
case 'b':
std::cout << "Second integer " << b << " is larger than first integer, " << a << std::endl;
break;
}
std::cout << system("cmd /c pause") << std::endl;
std::cout << "We can also use defined functions to check equivalency and assign variables based upon the result." << "\n";
std::cout << "Enter an integer: " << std::endl;
std::cin >> a;
std::cout << "Enter another integer: " << std::endl;
std::cin >> b;
larger = MAXIMUM(a,b);
smaller = MINIMUM(a,b);
std::cout << "Larger and smaller numbers determined by defined function: " << larger << ", " << smaller << std::endl;
std::cout << system("cmd /c pause") << std::endl;
return 0;
}
Obviously if I make two new variables, 'c' and 'd', there is no issue. Changing the type to int myself did not change the way the program behaved using Cygwin. Unusually the MinGW version was 8.1.0, while Cygwin was 7.4.0. I'm not sure if this means that it is simply an older version of the same compiler.
Again, I'm very new to this so I'm just quite confused as to why they would behave so differently. I was also under the impression that different compilers were completely different beasts that simply read from the same standard hymn sheet, so to speak.
Just curious as to what is going on here!
Cheers!

using int pointer in multiple couts

I'm quite new to the world of pointers in C/C++ so this may be quite an easy question for you:
The following C++-Code works normally
#include <iostream>
int main()
{
int theInt = 1337;
int & theReference = theInt;
int * thePointer = &theInt;
std::cout << "int: " << theInt << "\n";
std::cout << "referenz: " << theReference << "\n";
std::cout << "pointer: " << *thePointer << "\n";
std::cout << "pointer: " << *thePointer << "\n";
//std::cout << "foo" << "\n";
return 0;
}
but stops working when changing
//std::cout << "foo" << "\n";
to
std::cout << "foo" << "\n";
.
By "stops working" I mean: "is blocked by my norton security as a potential threat" (resulting in a return code of "0x76F531AF" if this is any help). Since norton normally doesn't interfere withe my programming I assume the double use of the int pointer in cout somehow results in a segfault...
Thx for your help!
PS:
I use Code::Blocks on Windows 8.1 with the GCC compiler and GDB debugger from TDM-GCC (version 4.7.1, 32 bit).
EDIT: removed deletion of pointer -> problem remains.
You can only delete objects created on the heap (using new or C-style malloc and such).
// allocate on the heap
int *intOnTheHeap = new int;
// do some stuff with it
*intOnTheHeap = 0;
(*intOnTheHeap)++;
std::cout << *intOnTheHeap << std::endl;
// deallocate
delete intOnTheHeap;
If you take a pointer to a local variable, it will point to an entry on the stack. You don't need to and shouldn't deallocate that memory yourself. The memory is "freed" by changing the stackpointer automatically when your variable runs out of scope (at the end of the function).
void myFunction() {
int localVariable;
int *pointerToLocalVariable = &localVariable;
// forbidden and unnecessary:
//delete pointerToLocalVariable;
// here (end of the block) the memory on the stack
// will be freed automatically
}
Since I got the same error after Norton-Interception in totally different contexts, this seems to be a case of Code::Blocks Norton incompatibility.

changing the location a pointer-to-pointer points to while maintaining the value of two other pointers

So, I have been trying to learn C++ and in the tutorial book that I am reading, I have gotten stuck on a problem of pointers-to-pointers. What I am trying to do change the pointer a pointer-to-pointer is pointing to without changing the value of the original pointer. Here's some code...
#include <iostream>
void testFunc(int **func_p_to_p) {
int *createdPointer = new int(10);
*func_p_to_p = createdPointer;
cout << **func_p_to_p << endl; //prints 10 as I expect
}
int main() {
int **main_p_to_p = NULL;
int *mainPointer = new int(5);
main_p_to_p = &mainPointer;
testFunc(main_p_to_p);
cout << **test << endl;//prints 10, I expect this...
cout << *mainPointer << endl; //prints 10 as well, I don't want that.
}
I asked a similar question about this earlier, here and I understand sort of what is going on. However, I can't seem to figure out how I would change where a pointer-to-pointer is pointing to without changing the original value. Could anyone explain how I would do this? Thanks.
In the line
*func_p_to_p = createdPointer;
you first follow your pointer-pointer to what it is pointing to: The address of int *mainPointer.
Next you assign a new value to this pointer, the value of createdPointer which is the address of new int(10).
So your mainPointer is now changed to target the same memory as createdPointer. Does this make any sense to you?
You can't do that. main_p_to_p points to mainPointer, so modifying *main_p_to_p modifies mainPointer, full stop.
You might be looking for this, though:
int main() {
int **main_p_to_p = NULL;
int *mainPointer = new int(5);
int *secondPointer = mainPointer;
main_p_to_p = &secondPointer;
// prints 5 5 5
cout << *mainPointer << " " << *secondPointer << " " << **main_p_to_p << std::endl;
testFunc(main_p_to_p);
// prints 5 10 10
cout << *mainPointer << " " << *secondPointer << " " << **main_p_to_p << std::endl;
}
Note that you don't need the main_p_to_p variable, but I left it in for consistency with the question.

Deleting a pointer to an automatic variable [duplicate]

This question already has an answer here:
What is the behavior of "delete" with stack objects? [duplicate]
(1 answer)
Closed 8 years ago.
Please look at this code
int i = 10; //line 1
int *p = &i; //line 2
delete p; //line 3
cout << "*p = " << *p << ", i = " << i << endl; //line 4
i = 20; //line 5
cout << "*p = " << *p << ", i = " << i << endl; //line 6
*p = 30; //line 7
cout << "*p = " << *p << ", i = " << i << endl; //line 8
What is the result of this code? Especially of line 3, 5 and 7? Do they invoke undefined behavior? What would be the output?
EDIT : I tried running it using g++, and it's compiling and running fine! I'm using MinGW on Windows 7.
What does Standard say in this context?
You can delete only a pointer if you have ever allocated it dynamically using new. In this case you have not allocated the pointer using new but simply defined and initialized it to point to a local variable of type int.
Invoking delete on a pointer not allocated dynamically using new is something called Undefined Behavior. In short, it means that anything on the earth can happen when such a code is executed and you can't complaint a bit to anyone on this planet.
delete p; is UB and so any further behavior can't be predicted or relied upon. You program might crash immediately or spend all your money or just exit from main() and pretend nothing happened.
Line 3 is definitely undefined behaviour, since you're trying to deleting memory at an address that is not on the heap.

c++ cout with float producing strange results

Currently I have the following:
float some_function(){
float percentage = 100;
std::cout << "percentage = " << percentage;
//more code
return 0;
}
which gives the output
percentage = 100
However when I add some std::endl like so:
float some_function(){
float percentage = 100;
std::cout << "percentage = " << percentage << std::endl;
//more code
return 0;
}
This gives the output:
percentage = 1000x6580a8
Adding more endl's just prints out more 0x6580a8's.
What could be causing this? This is compiled with gcc 4.4.3 on Ubuntu 10.04.
The function is written correctly. On my machine ( g++ 4.4.3 on Ubuntu 10.04 ) everything works smoothly.
Are you sure that the error isn't caused by some other part of the code ?
Your code is perfectly valid. I suspect that you could be smashing your stack or heap in some other part of your code as the most likely cause. 0x6580a8 is too short to be an object address. Also, he would never get the same address in two runs of the same program.
What if you tried \n ?
std::cout << "percentage = " << percentage << "\n";
Is this your actual code, or is there a different sort of stream instead of cout?
It's taking the address of the endl manipulator instead of applying it to the stream, which implies that it can't see the matching version of endl for the stream type you're using.
What happens if you use << "\n" << std::flush instead?