How to do a Stack of unique_ptr - c++11

Imagine you have a stack of unique_ptr to something (an int to simplify), like:
std::stack< std::unique_ptr<int> > numbers;
numbers.push( std::unique_ptr<int>( new int(42)) );
But if you try to use the top element, without getting it from the stack, you will get an compile error:
if( not numbers.empty() ){
auto lastone = numbers.top();
std::cout << "last " << *lastone << std::endl;
}
You should move out the element, use it, and then put again in the stack:
if( not numbers.empty() ){
auto lastone = std::move(numbers.top());
numbers.pop();
std::cout << "last " << *lastone << std::endl;
numbers.push( std::move(lastone) );
}
Is there a better way to do this?

If you don't intend to actually pop the element but just want to use it inplace, just use a reference:
auto& lastone = numbers.top();
std::cout << "last " << *lastone << std::endl;

Related

Create-Delete directory in a loop - returns success but was not complete at that time

( reported here
https://superuser.com/questions/1511981/windows-10-creating-and-deleting-directory-in-remote-location-netapp-in-a-loop this time with some more data and example program )
I am working on an issue - Create and deletion of directory on a loop in a small window gets incorrect response from API - it says directory deleted (returns true) but it stays there for some more time(say 20-30 milliseconds).
What can cause? The program runs fine on Windows 7 (NetApp storage or local disk). Windows 10 passes with local disk; but fails with NetApp storage. Need to sleep get the API (DeleteDirectory correct )
Wrote a code to reproduce in windows , c program (because admins wanted that way to rule out java, powershell etc )
#include "pch.h"
#include <iostream>
#include <cstdlib>
#include <windows.h>
#include <direct.h>
using namespace std;
int main()
{
const char* sleepTimeAsString = std::getenv("SLEEP_TIME_MILLIS");
const char* remoteRoot = std::getenv("REMOTE_UNC_PATH");
if (sleepTimeAsString == NULL) {
std::cout << "env SLEEP_TIME_MILLIS needed: " << '\n';
}
if (remoteRoot == NULL) {
std::cout << "env REMOTE_UNC_PATH needed: " << '\n';
}
std::cout << "set REMOTE_UNC_PATH=" << remoteRoot << '\n';
std::cout << "set SLEEP_TIME_MILLIS=" << sleepTimeAsString << '\n';
CreateDirectory(remoteRoot,NULL);
std::cout << "version 0.10 " << '\n';
std::cout << "created " << remoteRoot << '\n';
string path = remoteRoot;
string mynode = "/childdirectory";
string path2 = path + mynode;
DWORD error= GetLastError();
std::cout << error << '\n';
long sleepTime = atol(sleepTimeAsString);
for (int i = 0; i < 1000; i++) {
std::cout << "loop "<< i << '\n';
if (!CreateDirectory( path2.c_str(), NULL)) {
DWORD errorlooped = GetLastError();
std::cout <<"failed to create " << errorlooped << '\n';
exit(-1);
}
else {
std::cout << "success created " << path2.c_str() << '\n';
}
Sleep(sleepTime);
if (!RemoveDirectory(path2.c_str())) {
DWORD errorlooped = GetLastError();
std::cout << "failed remove "<< errorlooped << '\n';
exit(-1);
}
else {
std::cout << "success deleted " << path2.c_str() << '\n';
}
Sleep(sleepTime);
}
}
Result table: Once I provide sufficient sleep between calls the test started passing on this NetApp directory.
OS Disk Sleep Time(ms) Result
Win7 Local 0 PASS
Win7 Remote 0 PASS
WIn10 Local 0 PASS
WIn10 Remote (NetApp) 0 FAIL
WIn10 Remote (NetApp) 10 FAIL
WIn10 Remote (NetApp) 20 FAIL
WIn10 Remote (NetApp) 40 PASS
What should I investigate more on this issue (before getting back to System administrators ) - Ideas welcome.

GetRawInputDeviceInfo returns wrong syntax of USB HID device name in Windows 10

I have a code that I found on the internet that uses the function GetRawInputDeviceInfo, but it doesn't get the name of the device right. sometimes it doesn't get a name at all. I've searched for an answer and found out that people had this problem on windows XP and windows 7 to. I am using windows 10 so that doesn't really help me.
C++ - WinAPI get list of all connected USB devices (do i need to post the code itself? im new to stack overflow)
At the end of the day what I am trying to do is get the names of all the devices connected to my PC and print them out, but this function doesnt return the name of the mouse either, so if anyone has a suggestion on how to fix it or a better method to get the names Id'e love to hear you'r ideas. thanks in advance, -shon :)
EDIT2! the full code:
#include <windows.h>
#include <iostream>
#include <vector>
#include <string>
#include <set>
// Namespace
using namespace std;
// Main
int main()
{
// Program
cout << "USB Device Lister." << endl;
// Get Number Of Devices
UINT nDevices = 0;
GetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST));
// Got Any?
if (nDevices < 1)
{
// Exit
cout << "ERR: 0 Devices?";
cin.get();
return 0;
}
// Allocate Memory For Device List
PRAWINPUTDEVICELIST pRawInputDeviceList;
pRawInputDeviceList = new RAWINPUTDEVICELIST[sizeof(RAWINPUTDEVICELIST) * nDevices];
// Got Memory?
if (pRawInputDeviceList == NULL)
{
// Error
cout << "ERR: Could not allocate memory for Device List.";
cin.get();
return 0;
}
// Fill Device List Buffer
int nResult;
nResult = GetRawInputDeviceList(pRawInputDeviceList, &nDevices, sizeof(RAWINPUTDEVICELIST));
// Got Device List?
if (nResult < 0)
{
// Clean Up
delete[] pRawInputDeviceList;
// Error
cout << "ERR: Could not get device list.";
cin.get();
return 0;
}
std::set<std::string> DeviceList;
// Loop Through Device List
for (UINT i = 0; i < nDevices; i++)
{
// Get Character Count For Device Name
UINT nBufferSize = 0;
nResult = GetRawInputDeviceInfo(pRawInputDeviceList[i].hDevice, // Device
RIDI_DEVICENAME, // Get Device Name
NULL, // NO Buff, Want Count!
&nBufferSize); // Char Count Here!
// Got Device Name?
if (nResult < 0)
{
// Error
cout << "ERR: Unable to get Device Name character count.. Moving to next device." << endl << endl;
// Next
continue;
}
// Allocate Memory For Device Name
WCHAR* wcDeviceName = new WCHAR[nBufferSize + 1];
// Got Memory
if (wcDeviceName == NULL)
{
// Error
cout << "ERR: Unable to allocate memory for Device Name.. Moving to next device." << endl << endl;
// Next
continue;
}
// Get Name
nResult = GetRawInputDeviceInfo(pRawInputDeviceList[i].hDevice, // Device
RIDI_DEVICENAME, // Get Device Name
wcDeviceName, // Get Name!
&nBufferSize); // Char Count
// Got Device Name?
if (nResult < 0)
{
// Error
cout << "ERR: Unable to get Device Name.. Moving to next device." << endl << endl;
// Clean Up
delete[] wcDeviceName;
// Next
continue;
}
// Set Device Info & Buffer Size
RID_DEVICE_INFO rdiDeviceInfo;
rdiDeviceInfo.cbSize = sizeof(RID_DEVICE_INFO);
nBufferSize = rdiDeviceInfo.cbSize;
// Get Device Info
nResult = GetRawInputDeviceInfo(pRawInputDeviceList[i].hDevice,
RIDI_DEVICEINFO,
&rdiDeviceInfo,
&nBufferSize);
// Got All Buffer?
if (nResult < 0)
{
// Error
cout << "ERR: Unable to read Device Info.. Moving to next device." << endl << endl;
// Next
continue;
}
// Mouse
if (rdiDeviceInfo.dwType == RIM_TYPEMOUSE)
{
// Current Device
int id = rdiDeviceInfo.mouse.dwId; //device id
string s = "ID: " + std::to_string(id) + ", Type : MOUSE"; //device type is mouse
DeviceList.insert(s);
}
// Keyboard
else if (rdiDeviceInfo.dwType == RIM_TYPEKEYBOARD)
{
// Current Device
cout << endl << "Displaying device " << i + 1 << " information. (KEYBOARD)" << endl;
wcout << L"Name " << wcDeviceName << endl; //*Problem is here!* //
cout << "Keyboard mode: " << rdiDeviceInfo.keyboard.dwKeyboardMode << endl;
cout << "Number of function keys: " << rdiDeviceInfo.keyboard.dwNumberOfFunctionKeys << endl;
cout << "Number of indicators: " << rdiDeviceInfo.keyboard.dwNumberOfIndicators << endl;
cout << "Number of keys total: " << rdiDeviceInfo.keyboard.dwNumberOfKeysTotal << endl;
cout << "Type of the keyboard: " << rdiDeviceInfo.keyboard.dwType << endl;
cout << "Subtype of the keyboard: " << rdiDeviceInfo.keyboard.dwSubType << endl;
}
// Some HID
else // (rdi.dwType == RIM_TYPEHID)
{
// Current Device
cout << endl << "Displaying device " << i + 1 << " information. (HID)" << endl;
wcout << L"Device Name: " << wcDeviceName << endl;
cout << "Vendor Id:" << rdiDeviceInfo.hid.dwVendorId << endl;
cout << "Product Id:" << rdiDeviceInfo.hid.dwProductId << endl;
cout << "Version No:" << rdiDeviceInfo.hid.dwVersionNumber << endl;
cout << "Usage for the device: " << rdiDeviceInfo.hid.usUsage << endl;
cout << "Usage Page for the device: " << rdiDeviceInfo.hid.usUsagePage << endl;
}
// Delete Name Memory!
delete[] wcDeviceName;
}
// Clean Up - Free Memory
delete[] pRawInputDeviceList;
for (std::set<string>::iterator i = DeviceList.begin(); i != DeviceList.end(); ++i)
std::cout << *i << '\n';
// Exit
cout << endl << "Finnished.";
cin.get();
return 0;
}
In Windows there are two flavors of API calls: Unicode and ANSI. The former takes and returns UTF-16 encoded Unicode strings; the latter takes and returns 8-bit encoded strings (the exact encoding depends on the OS localization).
You choose which flavor you want to use by #defining (or not #defining) the macro UNICODE. Depending on that the function changes name, with an W or A suffix.
#ifdef UNICODE
#define GetRawInputDeviceInfo GetRawInputDeviceInfoW
#else
#define GetRawInputDeviceInfo GetRawInputDeviceInfoA
#endif
All the structures that may contain text data are also duplicated with the W or A suffixes.
Now your problem: you are not defining UNICODE so you are actually calling GetRawInputDeviceInfoA(), the ANSI flavor, that expects a char*, but you are passing a WCHAR*, that is a UNICODE string!
The solution is easy:
char* wcDeviceName = new char[nBufferSize + 1];
It is unfortunate that this function GetRawInputDeviceInfo() has its arguments overloaded, so it is declared as taking a void*, so the compiler cannot catch the error. If you were calling a simpler function, say SetWindowText() then you would have got a compiler error because of incompatible pointer type.
If you really want the full UNICODE name of the device, you may prefer keep the WCHAR string and then call the UNICODE function specifically:
WCHAR* wcDeviceName = new WCHAR[nBufferSize + 1];
...
GetRawInputDeviceInfoW(..., RIDI_DEVICENAME, wcDeviceName, ...);

std::unordered_map iterator returns erased keys, why and how to skip them

I am very new to C++ programming and have stumbled across a behaviour that confuses me and makes my coding harder. I have searched for answer a bit and could not find anything - I have also scrolled through C++ reference pages and that did not help either (please don't crucify me if the answer is in there - the page isn't role model for explaining things). Maybe I am missing something really obvious.
Could someone explain, the following behaviour of std::unordered_map ?
std::unordered_map<std::string, std::string> test_map;
test_map["test_key_1"] = "test_value_1";
test_map["test_key_2"] = "test_value_2";
std::cout << "'test_key_1' value: " << test_map["test_key_1"] << std::endl; // This returns "test_value_1"
std::cout << "test_map size before erase: " << test_map.size() << std::endl; // This returns 2
test_map.erase("test_key_1");
std::cout << "test_map size after erase: " << test_map.size() << std::endl; // This returns 1
std::cout << "'test_key_1' value after erase: " << test_map["test_key_1"] << std::endl; // This returns empty string
std::cout << "'non_existing_key' value: " << test_map["non_existing_key"] << std::endl; // This returns empty string
test_map.rehash(test_map.size()); // I am doing this because vague hints from internet, code behaves
// same way without it.
for (std::unordered_map<std::string, std::string>::iterator it = test_map.begin();
it != test_map.end(); ++it)
{
std::cout << "Key: " << it->first << std::endl;
}
// Above loop return both 'test_key_1' and 'test_key_2'.
// WHY!?
Why iterator is returning items that were already erased ? How can I make iterator return only items that are present in map ?
I will be grateful for any help, as I am really lost.
You are using operator[] to access previously erased elements which
Returns a reference to the value that is mapped to a key equivalent to key, performing an insertion if such key does not already exist.
If you need just to search for given key, use find method that returns map.end() if element was not found.

Using std::unique_ptr and lambdas to advance a state of an object

When advancing the state of an object, use of std::swap works well for simple objects and pointer swaps. For other in place actions, Boost.ScopeExit works rather well, but it's not terribly elegant if you want to share exit handlers across functions. Is there a C++11 native way to accomplish something similar to Boost.ScopeExit but allow for better code reuse?
(Ab)use std::unique_ptr's custom Deleters as a ScopeExitVisitor or Post Condition. Scroll down to ~7th line of main() to see how this is actually used at the call site. The following example allows for either std::function or lambdas for Deleter/ScopeExitVisitor's that don't require any parameters, and a nested class if you do need to pass a parameter to the Deleter/ScopeExitVisitor.
#include <iostream>
#include <memory>
class A {
public:
using Type = A;
using Ptr = Type*;
using ScopeExitVisitorFunc = std::function<void(Ptr)>;
using ScopeExitVisitor = std::unique_ptr<Type, ScopeExitVisitorFunc>;
// Deleters that can change A's private members. Note: Even though these
// are used as std::unique_ptr<> Deleters, these Deleters don't delete
// since they are merely visitors and the unique_ptr calling this Deleter
// doesn't actually own the object (hence the label ScopeExitVisitor).
static void ScopeExitVisitorVar1(Ptr aPtr) {
std::cout << "Mutating " << aPtr << ".var1. Before: " << aPtr->var1;
++aPtr->var1;
std::cout << ", after: " << aPtr->var1 << "\n";
}
// ScopeExitVisitor accessing var2_, a private member.
static void ScopeExitVisitorVar2(Ptr aPtr) {
std::cout << "Mutating " << aPtr << ".var2. Before: " << aPtr->var2_;
++aPtr->var2_;
std::cout << ", after: " << aPtr->var2_ << "\n";
}
int var1 = 10;
int var2() const { return var2_; }
// Forward declare a class used as a closure to forward Deleter parameters
class ScopeExitVisitorParamVar2;
private:
int var2_ = 20;
};
// Define ScopeExitVisitor closure. Note: closures nested inside of class A
// still have access to private variables contained inside of A.
class A::ScopeExitVisitorParamVar2 {
public:
ScopeExitVisitorParamVar2(int incr) : incr_{incr} {}
void operator()(Ptr aPtr) {
std::cout << "Mutating " << aPtr << ".var2 by " << incr_ << ". Before: " << aPtr->var2_;
aPtr->var2_ += incr_;
std::cout << ", after: " << aPtr->var2_ << "\n";
}
private:
int incr_ = 0;
};
// Can also use lambdas, but in this case, you can't access private
// variables.
//
static auto changeStateVar1Handler = [](A::Ptr aPtr) {
std::cout << "Mutating " << aPtr << ".var1 " << aPtr->var1 << " before\n";
aPtr->var1 += 2;
};
int main() {
A a;
std::cout << "a: " << &a << "\n";
std::cout << "a.var1: " << a.var1 << "\n";
std::cout << "a.var2: " << a.var2() << "\n";
{ // Limit scope of the unique_ptr handlers. The stack is unwound in
// reverse order (i.e. Deleter var2 is executed before var1's Deleter).
A::ScopeExitVisitor scopeExitVisitorVar1(nullptr, A::ScopeExitVisitorVar1);
A::ScopeExitVisitor scopeExitVisitorVar1Lambda(&a, changeStateVar1Handler);
A::ScopeExitVisitor scopeExitVisitorVar2(&a, A::ScopeExitVisitorVar2);
A::ScopeExitVisitor scopeExitVisitorVar2Param(nullptr, A::ScopeExitVisitorParamVar2(5));
// Based on the control of a function and required set of ScopeExitVisitors that
// need to fire use release() or reset() to control which visitors are used.
// Imagine unwinding a failed but complex API call.
scopeExitVisitorVar1.reset(&a);
scopeExitVisitorVar2.release(); // Initialized in ctor. Use release() before reset().
scopeExitVisitorVar2.reset(&a);
scopeExitVisitorVar2Param.reset(&a);
std::cout << "a.var1: " << a.var1 << "\n";
std::cout << "a.var2: " << a.var2() << "\n";
std::cout << "a.var2: " << a.var2() << "\n";
}
std::cout << "a.var1: " << a.var1 << "\n";
std::cout << "a.var2: " << a.var2() << "\n";
}
Which produces:
a: 0x7fff5ebfc280
a.var1: 10
a.var2: 20
a.var1: 10
a.var2: 20
a.var2: 20
Mutating 0x7fff5ebfc280.var2 by 5. Before: 20, after: 25
Mutating 0x7fff5ebfc280.var2. Before: 25, after: 26
Mutating 0x7fff5ebfc280.var1 10 before
Mutating 0x7fff5ebfc280.var1. Before: 12, after: 13
a.var1: 13
a.var2: 26
On the plus side, this trick is nice because:
Code used in the Deleters can access private variables
Deleter code is able to be centralized
Using lambdas is still possible, though they can only access pubic members.
Parameters can be passed to the Deleter via nested classes acting as closures
Not all std::unique_ptr instances need to have an object assigned to them (e.g. it's perfectly acceptable to leave unneeded Deleters set to nullptr)
Changing behavior at runtime is simply a matter of calling reset() or release()
Based on the way you build your stack it's possible at compile time to change the safety guarantees on an object when the scope of the std::unique_ptr(s) go out of scope
Lastly, using Boost.ScopeExit you can forward calls to a helper function or use a conditional similar to what the Boost.ScopeExit docs suggest with bool commit = ...;. Something similar to:
#include <iostream>
#include <boost/scope_exit.hpp>
int main() {
bool commitVar1 = false;
bool commitVar2 = false;
BOOST_SCOPE_EXIT_ALL(&) {
if (commitVar1)
std::cout << "Committing var1\n"
if (commitVar2)
std::cout << "Committing var2\n"
};
commitVar1 = true;
}
and there's nothing wrong with that, but like was asked in the original question, how do you share code without proxying the call someplace else? Use std::unique_ptr's Deleters as ScopeExitVisitors.

StackWalk64() returns a single frame

When trying to obtain the call stack of a thread of some process, I always get a single same frame, although it is for sure has more (at least 5 frames).
StackWalk64() always succeeds on the first call - return a frame with:
AddrPC.Offset = 18446744072850558156
But, immediately on the second call it fails with error id 998-ERROR_NOACCESS (it might be that this error is not because of this call, as MSDN says).
Moreover, trying to resolve this address into its symbol name with SymFromAddr() fails with error 126-ERROR_MOD_NOT_FOUND (after successful SymInitialize(m_processHandler,NULL,TRUE) call).
Here is the code:
#ifdef _M_IX86
//
// Disable global optimization and ignore /GS waning caused by
// inline assembly.
//
#pragma optimize( "g", off )
#pragma warning( push )
#pragma warning( disable : 4748 )
#endif
bool EchoProfiler::getThreadStackTrace(__in HANDLE h_thread, __out vector<DWORD64> &framesVec)
{
CONTEXT threadContext;
if (GetThreadContext(h_thread, &threadContext) == 0)
{
cout << "Error: GetThreadContext() failed with error ID " << GetLastError() << endl;
return false;
}
//initialize stack frame
DWORD MachineType;
STACKFRAME64 StackFrame;
ZeroMemory( &StackFrame, sizeof( STACKFRAME64 ) );
MachineType = IMAGE_FILE_MACHINE_I386;
StackFrame.AddrPC.Offset = threadContext.Eip;
StackFrame.AddrPC.Mode = AddrModeFlat;
StackFrame.AddrFrame.Offset = threadContext.Ebp;
StackFrame.AddrFrame.Mode = AddrModeFlat;
StackFrame.AddrStack.Offset = threadContext.Esp;
StackFrame.AddrStack.Mode = AddrModeFlat;
PVOID contextRec = (MachineType == IMAGE_FILE_MACHINE_I386) ? NULL : &threadContext;
int i=0;
// enumerate all the frames in the stack
for (i=1 ; ; i++)
{
if (StackWalk64( MachineType, targetProcessHandler, h_thread, &StackFrame,
contextRec, NULL, SymFunctionTableAccess64, SymGetModuleBase64, NULL ) == false)
{
// in case it failed or we have finished walking the stack.
cout << "Error: StackWalk64() failed with error ID " << GetLastError() << endl;
i--;
break;
// return false;
}
if ( StackFrame.AddrPC.Offset != 0 )
{
// Valid frame.
cout << "Frame #" << i << " address - " << StackFrame.AddrPC.Offset << endl;
framesVec.push_back(StackFrame.AddrPC.Offset);
}
else
{
// Base reached.
break;
}
}
//cout << "StackWalk64 found " << i << " stack frames:" << endl;
//i = 1;
//for (FramesConstItr itr=framesVec.begin() ; itr != framesVec.end() ; itr++ , i++)
// cout << i << " - " << *itr << endl;
return true;
}
#ifdef _M_IX86
#pragma warning( pop )
#pragma optimize( "g", on )
#endif
what could it be?
Solution:
I missed the part said that the context structure must be initialize properly.
Adding the following solved my problem:
memset(&threadContext, 0, sizeof(CONTEXT));
threadContext.ContextFlags = CONTEXT_FULL;
Thanks
For anyone running into this issue in the future, I also suffered from it in our own local codebase when getting stack information from a different process to the current one. The cause was that we were missing PROCESS_VM_READ when getting a handle on the process using OpenProcess().

Resources