ALL,
for( std::map<int, std::vector<Foo *> >::iterator it = fkFields.begin(); it != fkFields.end() && !found; it++ )
{
for( std::vector<Foo *>::iterator it1 = it->second.begin(); it1 < it->second.end(); ++it1 )
{
if( refTableOrig == (*it1)->GetReferencedTableName() )
{
found = true;
delete (*it1);
(*it1) = NULL;
it->second.erase( it1 );
}
}
if( found )
fkFields.erase( it );
}
This code above is crashing when there is only 1 element in the std::vector because the code will try to go over the iterator::end().
Also I can't just vector.erase()/vector.remove() because the vector contains pointers and the memory has to be deleted.
So what is the proper way to delete the pointer to the element from the vector.
P.S.: This is different from all other questions since my vector holds pointers and not objects.
TIA!!
Firstly, you should check it1 != it->second.end().
Secondly, what is the return value of vector::erase ?
An iterator pointing to the new location of the element that followed the last element erased by the function call.
so you should use this information and rewrite your inner for loop as follows
for( std::vector<Foo *>::iterator it1 = it->second.begin(); it1 != it->second.end(); )
// [1] changed it1 != it->second.end() [2] removed ++it1
{
if( refTableOrig == (*it1)->GetReferencedTableName() )
{
found = true;
delete (*it1);
(*it1) = NULL;
it1 = it->second.erase( it1 );
}
else
++it1;
}
Related
Following code works for sorting of the list (Peter,10) (John,32) (Mary,50) (Carol,31)
Ordered lists:
List 1: (Carol,31) (Carol,31) (John,32) (Mary,50)
however the peter is lost and carol is getting repeated, please help to suggest where Iam going wrong. WHat do I need to change in the loop to get this correct
LinkedList& LinkedList::order()
{
int swapped;
Node *temp;
Node *lptr = NULL;
temp=head;
// Checking for empty list
do
{
swapped = 0 ;
current = head;
while (current->get_next() != lptr)
{
if (current->get_data() > current->get_next()->get_data())
{
temp->set_Node(current->get_data());
current->set_Node(current->get_next()->get_data());
current->get_next()->set_Node(temp->get_data());
swapped = 1;
}
current = current->get_next();
}
lptr = current;
}
while (swapped);
return *this;
}
I'm trying to delete duplicate nodes from a sorted linked list. The code I used is -
Node* RemoveDuplicates(Node *head)
{
struct Node *ptr = head;
int var = ptr->data;
while(ptr != NULL)
{
var = ptr->data;
if(var == ptr->next->data)
{
ptr->next = ptr->next->next;
else
ptr = ptr->next;
}
return head;
}
Forget the free(ptr) statement, other than that I guess everything is fine but the above code is not working.
Is there any problem in the logic as I saw a similar code online but with one additional pointer?
Thanks in advance.
if(var == ptr->next->data)
should be
if (ptr->next != NULL && var == ptr->next->data)
No guarantees in your code that the next pointer is not null,
I have been trying to do a simple OPC UA client server application using the open62541 stack. I can access the value from the open62541 implemented server. But i need to know, how a array value from the server can be interpreted/retrieved by the open62541 client?
Ex:
This is how i do for single value-
UA_Client_readValueAttribute(client, UA_NODEID_STRING(1, "value"), &value);
if(status == UA_STATUSCODE_GOOD &&
UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_INT32])) {
printf("value is: %i\n", *(UA_Int32*)value.data);
}
Here is an example how to read the namespace array.
It works in the same way as any other array value:
UA_ReadRequest request;
UA_ReadRequest_init(&request);
UA_ReadValueId id;
UA_ReadValueId_init(&id);
id.attributeId = UA_ATTRIBUTEID_VALUE;
id.nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_NAMESPACEARRAY);
request.nodesToRead = &id;
request.nodesToReadSize = 1;
UA_ReadResponse response = UA_Client_Service_read(client, request);
UA_StatusCode retval = UA_STATUSCODE_GOOD;
if(response.responseHeader.serviceResult != UA_STATUSCODE_GOOD)
retval = response.responseHeader.serviceResult;
else if(response.resultsSize != 1 || !response.results[0].hasValue)
retval = UA_STATUSCODE_BADNODEATTRIBUTESINVALID;
else if(response.results[0].value.type != &UA_TYPES[UA_TYPES_STRING])
retval = UA_STATUSCODE_BADTYPEMISMATCH;
if(retval != UA_STATUSCODE_GOOD) {
UA_ReadResponse_deleteMembers(&response);
return retval;
}
retval = UA_STATUSCODE_BADNOTFOUND;
UA_String *ns = (UA_String *)response.results[0].value.data;
for(size_t i = 0; i < response.results[0].value.arrayLength; ++i){
printf("The NS is %*.s", (int)ns[i].length, ns[i].data);
}
UA_ReadResponse_deleteMembers(&response);
The important thing is that response.results[0].value.data holds the array, and response.results[0].value.arrayLength the length of the array itself.
I am trying to read a .graphml that yEd (yEd) generates. I am able to read simple and manually-generated .graphml files but the yEd files contains several properties to be defined. Does any one has a running example that show how to deal with such yEd files?
The yED file must be filtered to remove all the yEd stuff that boost::read_graphml does not recognize. If all you want is the vertices and edges, this is simple enough. However, if you do want some of the attributes, then it becomes more complex, and will depend on what you need.
Here is some code that filters out all the yED stuff, except the text of the node labels, which is converted to the simplest possible node label attribute that boost::read_graphml can parse and store in a bundled property.
/**
Check for a yEd file
#param[in] n the filename
#return true if the file weas written by yED
The input file is copied to a new file graphex_processed.graphml
If the intput file was NOT produced by yEd, then the copy is perfect
If input was produced by yEd then the copy is filtered so that it can be
read by boost::read_graphml
Most of the yEd stuff is discarded, except for the node labels
the text of which are copied to a simple node attribute "label"
*/
bool cGraph::IsGraphMLbyYED(const std::wstring& n)
{
bool yEd = false;
// open the input file
std::ifstream fin;
fin.open(n.c_str(), std::ifstream::in);
if( ! fin.is_open() ) {
return false;
}
// open the output file
std::ofstream fout;
fout.open("graphex_processed.graphml", std::ifstream::out );
if( ! fout.is_open() ) {
return false;
}
// loop over input file lines
fin.clear();
char buf[1000];
while( fin.good() ) {
fin.getline( buf,999 );
std::string l( buf );
// check for file produced by yEd
if( l.find("<!--Created by yFiles") != -1 ) {
yEd = true;
// convert NodeLabel text to simple label attribute
fout << "<key id=\"key0\" for=\"node\" attr.name=\"label\" attr.type=\"string\" />\n";
}
// check for file already identified as yEd
if( yEd ) {
// filter out yED attributes
if( l.find("<key") != -1 ) {
continue;
}
// convert NodeLabel text
if( l.find("<y:NodeLabel") != -1 ) {
int p = l.find(">")+1;
int q = l.find("<",p);
std::string label = l.substr(p,q-p);
fout << "<data key=\"key0\">" << label << "</data>\n";
continue;
}
// filter out outher yEd stuff
if( l.find("<y:") != -1 ) {
continue;
}
if( l.find("</y:") != -1 ) {
continue;
}
if( l.find("<data") != -1 ) {
continue;
}
if( l.find("</data") != -1 ) {
continue;
}
}
// copy input line to output
fout << buf << std::endl;
}
// close files
fin.close();
fout.close();
// return true if yED file
return yEd;
}
Here is some code to read the filtered file
void cGraph::ReadGraphML(const std::wstring& n)
{
// check if file was produced by yEd
IsGraphMLbyYED( n );
boost::dynamic_properties dp;
dp.property("label", boost::get(&cVertex::myName, myGraph));
myGraph.clear();
std::ifstream fin;
fin.open("graphex_processed.graphml", std::ifstream::in);
if( ! fin.is_open() ) {
return;
}
boost::read_graphml( fin, myGraph, dp );
}
If you want to see an example of this running in an application, take a look at Graphex, a GUI for the BGL, which can read yEd files using this code.
Try this workaround:
https://stackoverflow.com/a/55807107/4761831
I just inherited a class and removed some codes that cause the exception.
I am trying to implement a simple singly linked list of integers which are to be sorted upon insertion in Visual Studio c++ 2010 express.
The problem is that when I create a new node and call the .getValue() function on it, the correct number is returned, however somehow that is being lost when I try calling getValue() on a node already in the list. The node might not be inserted into the list correctly, however I can't find why that would be the case. Some other value which looks like a reference value or something is displayed instead of the correct value.
I added current to the watch window when debugging but was still unable to see any of my variables other than the give value to be inserted. I am new to visual studio so I'm not sure if I'm missing something there. Here is my code:
#include "Node.h";
#include <iostream>
//namespace Linked{
//The first two constructors would be the first in the linked list.
Node::Node(void){
value = 0;
next = 0;
}
Node::Node(int setValue){
value = setValue;
next = 0;
}
Node::Node(int setValue,Node *nextNode){
value = setValue;
next = nextNode;
}
Node * Node::getNext(){
return next;
}
void Node::setNext(Node newNext){
next = &newNext;
}
int Node::getValue(){
return value;
}
bool Node::isEqual(Node check){
return value==check.getValue()&&next == check.getNext();
}
/*
int main(){
int firstInt, secondInt;
std::cin>>firstInt;
Node first = Node(firstInt);
std::cout<<"Enter second int: ";
std::cin>>secondInt;
Node second = Node(secondInt, &first);
std::cout<<"Second: "<<second.getValue()<<"\nFirst: "<<(*second.getNext()).getValue();
system("pause");
}*/
Here is the linked list:
//LinkedList.cpp
LinkedList::LinkedList(void)
{
head = 0;
size = 0;
}
LinkedList::LinkedList(int value)
{
head = &Node(value);
size = 1;
}
void LinkedList::insert(int value){
if(head == 0){
Node newNode = Node(value);
head = &newNode;
std::cout<<"Adding "<<(*head).getValue()<<" as head.\n";
}else{
std::cout<<"Adding ";
Node current = *head;
int numChecked = 0;
while(size<=numChecked && (((*current.getNext()).getValue())<value)){
current = (*(current.getNext()));
numChecked++;
}
if(current.isEqual(*head)&¤t.getValue()<value){
Node newNode = Node(value, ¤t);
std::cout<<newNode.getValue()<<" before the head: "<<current.getValue()<<"\n";
}else{
Node newNode = Node(value,current.getNext());
current.setNext(newNode);
std::cout<<newNode.getValue()<<" after "<<current.getValue()<<"\n";
}
}
size++;
}
void LinkedList::remove(int){
}
void LinkedList::print(){
Node current = *head;
std::cout<<current.getValue()<<" is the head";
int numPrinted = 0;
while(numPrinted<(size-1)){
std::cout<<(current.getValue())<<", ";
current = (*(current.getNext()));
numPrinted++;
}
}
int main(){
int a[5] = {30,20,25,13,2};
LinkedList myList = LinkedList();
int i;
for(i = 0 ; i<5 ; i++){
myList.insert(a[i]);
}
myList.print();
system("pause");
}
Any guidance would be greatly appreciated!
When you create nodes in insert, you're allocating them off the stack, which means that they'll be lost after the function returns.
Get them off the heap with:
Node * newNode=new Node(value);
When you use:
Node newNode=Node(value);
You're allocating that object on the stack, which means that pointers:
&newNode
to it are only valid until that function returns. If you use heap memory this is no longer an issue, but it does mean that you have to implement a destructor for your list which goes through and deletes each node.