I'm using a library written in C and the library provides headers which only use void*. The library is used to create a kind of graph, which is stored inside the C data-base. The headers return void* to the nodes in the graph. To create the graph, I need to parse a stack of lets say node names. In parallel to the stack of node names, I need to maintain a stack void* for the nodes. I have something like this:
std::stack < void* > nodeStack;
while (!nodeNameStack.empty()) {
// check if nodeNamestack.front() meets some criteria
nodeStack.push(C_API_To_Create_Node(nodeNameStack.pop()));
// Do some processing
// check if nodeStack.size() >= 2
void *node1 = nodeStack.pop()
void *node2 = nodeStack.pop()
// Above line issues error saying void value not ignored as it ought to be..
I'm not sure what the issue is, as we guarantee nodeStack size is atleast 2. I would appreciate any suggestions to overcome this error..
std::stack::pop() doesn't return the element removed. You have to read it with top() before popping it.
2 Things
A) you forgot ;'s after nodeStack.pop().
B) .pop() returns void which is why you are getting the error. .pop() just removes the element from the stack. Use .top() to get the element, then .pop() to remove it.
The prototype for stack::pop is
void pop ( );
Therefore it does not return anything hence the warning. Perhaps you meant to use stack::top
Related
I'd like to do the following:
std::stack <int> s;
int h = 0;
s.push(2);
h = s.pop();
Such as to have h hold the value 2. When I try my method, I get “void value not ignored as it ought to be”.
Is this not the intention of the .pop() method? What is the preferred way to do this?
The standard library containers separate top() and pop(): top() returns a reference to the top element, and pop() removes the top element. (And similarly for back()/pop_back() etc.).
There's a good reason for this separation, and not have pop remove the top element and return it: One guiding principle of C++ is that you don't pay for what you don't need. A single function would have no choice but to return the element by value, which may be undesired. Separating concerns gives the user the most flexibility in how to use the data structure. (See note #3 in the original STL documentation.)
(As a curiousum, you may notice that for a concurrent container, a pop-like function is actually forced to remove and return the top value atomically, since in a concurrent context, there is no such notion as "being on top" (or "being empty" for that matter). This is one of the obvious examples of how concurrent data structures take a significant performance hit in order to provide their guarantees.)
You can use:
h = s.top();
then after that use(if you want to remove the most recent value otherwise do nothing)
s.pop();
It works the same way!!
You can actually use s.top() to store the element and then pop it using
s.pop().
use
int h=s.top();
s.pop()
instead of
int h=s.pop()
You cannot directly assign s.pop() to some data type, as s.pop() removes element from stack and returns nothing.
S.pop() does not return any value. Because pop() is void function.
If you want to see the top of the stack then it will be S.top(). If you store this value then write value = S.top().
I am programming a method called popButtom () in C ++ using stacks.
The method must do the following: ¨Eliminate the element of the base and leave the stack in the same order but without the element elminado¨, I can not use pop or push.
For example:
ini stack:
A
B
C
D
end stack:
A
B
C
I have programmed the following, but I do not know that I can have bad:
void popFull()
{
struct node *A, *B;
top1 = top;
while (top1 != NULL)
{
B = top1->ptr;
A = top1;
B->ptr = A;
top1 = B;
}
}
Regards
Mariam
So, I'll see what I can do to answer this, though it would be very helpful if you could include a more complete version of your code, because I'm not entirely sure what type of data structure some of your variables are because there are no declarations included. As well, could you clarify what you mean by "but I do not know that I can have bad:"? I think these changes would make your question easier to answer.
In any case, I'll try to answer your question by interpreting it as "How do I eliminate the element at the base and leave the stack in the same order, not using pop or push." (I assume this is some sort of assignment?)
To that end I'll propose several options. C++11 has another function that isn't push() or pop() which you can use by doing stack.emplace() which just adds an item to the top of the stack. It is functionally the same as stack.push but it might be a nice hack. It's obviously a bit of a technicality, and there actually is a difference (it's very nuanced though, here's a link if you're interested: C++: Stack's push() vs emplace()) but you might be able to get away with it.
Next, I'll say that if you cannot use stack.pop() or stack.push() this next option is a possibility, but only if you initialize stack with a container class of vector, because otherwise the items are not contiguous in memory and there is no guarantee that it will work. I'm referring to, of course, pointer arithmetic. Here: Copy std::stack into an std::vector is another answer that deals with this, but I'll give a brief overview of what they did. If you initialize your stack using a std::vector as in this example in the documention, you can then copy your stack to a vector, and then operate freely on that vector, then copy back to a stack.
Here's what I mean (keep in mind this only works if the container class is vector because it seem like you're just designing a function to take in an argument and not initialize your own).
//this is how it will have to have been initailized
//for this to be guarenteed to work
std::stack<int, std::vector<int>> myStack;
int* begin = &stack.top()+1;
int* end = being+stack.size();
std::vector stackContents(begin,end);
And hurray, smooth sailing from here, now you can remove the item freely using your method of choice on the vector. Then, when you've modified the vector, you can create another stack to return by doing the opposite:
std::stack<int, std::vector<int>> newStack (stackContents);
return newStack;
Obviously this is a major workaround, and in the real world pop() and push() are useful functions and are included for a reason. This might actually be a good time to touch on the idea that stacks are designed to be accessed from either end. That's why it's been categorized as Last In First Out, because the idea of order matters and trying to circumvent that order means that a stack wasn't the proper data structure to use in the first place. Either way, that's my two cents, and I hope this helps.
I used the search function, and while I found some similar threads I did not find one that exactly covered my issue.
I am attempting to do a look up of a BST using recursion and an in-order traversal , so I want to keep track of the position of the elements.
I have the following code, but it is not doing what I want it to do. It is doing the correct traversal, but the position is not correct.
void startProces(int x)
{
void inOrder(x,*n,*Position)
}
void inOrder(int x, Node *n, int *Position)
{
int counter = *Position;
counter++;
Position = &counter;
}
This is a homework assignment, so please avoid giving me a direct solution. Also please avoid giving me a suggestion that involve having to rewrite the function parameters as I'm locked in. I would appreciate insight on why my position value is not increment properly. I know that my function currently isn't doing anything once it finds the value. I was planning on implementing that once I figured out this issue.
Clarification: I have an insert function, not shown here. If I insert the nodes (15,5,3,12,10,13,6,7,16,20,18,23) I get the in-order traversal (3,5,6,7,10,12,13,15,16,18,20,23). I want this to correspond to (1,2,3,4,5,6,7,8,9,10,11,12). Eventually when I run something like startProcess(10), I want inOrder to print 5.
Your code copies a variable on the stack and passes the address of that variable. So, for each child node, the value will always be the parent node's value plus one, instead of the previously traversed node's value plus one.
Specifically, this line copies it...
int counter = *Position;
The variable Position is a pointer, where counter is a local variable. The pointer points to the address you give it using &. Every time you call inOrder, it creates a new counter variable that's scoped to that function call.
So, this line...
Position = &counter;
sets the pointer to the counter instance in the above function call. All you need to do is pass a pointer to one specific instance instead of the copies.
using : VC++ 2013
concurrency::concurrent_vector<datanode*> dtnodelst
Occasionally when I do dtnodelst->at(i) .... I am getting an invalid address (0XCDCD.. ofc)
which shouldn't be the case cause after I do push back, I never delete or remove any of the itms ( even if I delete it should have returned the deleted old address... but I am not ever deleting so that is not even the case )
dtnodelst itm = new dtnodelst ();
....
dtnodelst->push_back(itm);
any ideas on what might be happening ?
p.s. I am using windows thread pool. some times .. I can do 8million inserts and find and everything goes fine .... but sometimes even 200 inserts and finds will fail. I am kind of lost. any help would be awesomely appreciated!!
thanks and best regards
actual code as an fyi
p.s. am I missing something or is it pain in the ass to past code with proper formatting ? I remember it being auto align before ... -_-
struct datanode {
volatile int nodeval;
T val;
};
concurrency::concurrent_vector<datanode*> lst
inline T find(UINT32 key)
{
for (int i = 0; i < lst->size(); i++)
{
datanode* nd = lst->at(i);
//nd is invalid sometimes
if (nd)
if (nd->nodeval == key)
{
return (nd->val);
}
}
return NULL;
}
inline T insert_nonunique(UINT32 key, T val){
datanode* itm = new datanode();
itm->val = val;
itm->nodeval = key;
lst->push_back(itm);
_updated(lst);
return val;
}
The problem is using of concurrent_vector::size() which is not fully thread-safe as you can get reference to not yet constructed elements (where memory contains garbage). Microsoft PPL library (which provides it in concurrency:: namespace) uses Intel TBB implementation of concurrent_vector and TBB Reference says:
size_type size() const |
Returns: Number of elements in the vector. The result may include elements that are allocated but still under construction by concurrent calls to any of the growth methods.
Please see my blog for more explanation and possible solutions.
In TBB, the most reasonable solution is to use tbb::zero_allocator as underlying allocator of concurrent_vector in order to fill newly allocated memory with zeroes before size() will count it too.
concurrent_vector<datanode*, tbb::zero_allocator<datanode*> > lst;
Then, the condition if (nd) will filter out not-yet-ready elements.
volatile is no substitute for atomic<T>. Do not use volatile in some attempt to provide synchronization.
The whole idea of your find call doesn't make sense in a concurrent context. As soon as the function iterates over one value, it could be mutated by another thread to be the value you're looking for. Or it could be the value you want, but mutated to be some other value. Or as soon as it returns false, the value you're seeking is added. The return value of such a function would be totally meaningless. size() has all the same problems, which is a good part of why your implementation would never work.
Inspecting the state of concurrent data structures is a very bad idea, because the information becomes invalid the moment you have it. You should design operations that do not require knowing the state of the structure to execute correctly, or, block all mutations whilst you operate.
I declare:
typedef std::tr1::shared_ptr<ClassA> SharedPtr;
And then:
std::vector<SharedPtr> mList;
And:
typedef std::vector<SharedPtr>::iterator ListIterator;
The return of mList.size() is 0, but when I use iterators, it iterates over the vector which is empty ! This is how I use the iterator:
for(ListIterator it = mList.begin(); it!=mList.end(); it++)
(*it)->someMethod();
It executes the "someMethod()" and then it throws Segmentation Fault. How iterators is iterating in an empty vector ????
More information
I'm using GTK, so this is how I pass the main object:
g_signal_connect(G_OBJECT(widget), "event", G_CALLBACK(&ClassB::fun), this)
The this is the ClassB itself.
And then I receive it like this:
gboolean ClassB::fun(GtkWidget *widget, GdkEvent *event, ClassB *data)
{
// The mList is here, and is accessed like this:
// data->mList
}
The mList is declared as I cited, when I access other attribute, let's say data->xxx it works and it's fine, the problem is occuring only with mList and this attribute is not dynamically allocated.
I've checked the memory address of the *data and of the this, they're the same address.
I've solved the problem, the object class B was being destroyed after some scope. Anyway, thank you guys !
Add this assert before your for loop. If you trigger it, mList is corrupted. E.g., perhaps the containing class is also corrupted/dead/not what you think it is.
assert( mList.size() != 0 || mList.begin() == mList.end() )
Did you paste your for loop exactly? If you accidentally had a stray ; at the end of your for loop, it would in fact seem to execute one iteration and make the call as you're seeing.
Have you printed out the list size directly before the loop to make sure that it is in fact empty? the only other option I can think of is that the list isn't in fact empty, but contains one or more garbage elements.
Maybe not the answer in your case, but beware of spurious trailing semicolons on for loops.
I often write this and have to give myself a good kicking when I find it...
for(ListIterator it = mList.begin(); it!=mList.end(); it++);
(*it)->someMethod();
It could account for the symptom of someMethod being called even when mList is empty (assuming 'it' is in scope from elsewhere somehow).
Failing that, I'd guess mList is corrupted before your for loop runs. IIRC vectors may store begin, end AND size separately, so if something else stomps on "end" (eg zeroing it), then begin !=end, but size == 0.
You could always just rewrite the code in an iterator-free way (OK, I know this could just be masking the issue, but, hey...)
for (int i=0; i< mList.size(); i++)
mlist[i]->someMethod();
Is the list being modified during the loop, maybe through the callback?