What is this C++ map doing? - c++

I have a global variable, "testGrid" which I am attempting to create a map to, so that I can reference it with a string. The map seems like it works in that I can assign values to the grid, but it is not assigning them to "testGrid" as I intend it to.
Is the map creating a new grid, separate from the global variable? How can I get the map to reference the grid correctly? In this code, the output from the two tests should be identical.
#include <iostream>
#include <map>
using namespace std;
struct signalGrid{
double signal[20][200];
signalGrid();
};
void mapTest(std::map<string,signalGrid> &temp_map);
map<string,signalGrid> signalIndex;
signalGrid testGrid;
int main(){
int i;
mapTest(signalIndex);
for(i=0;i<5;i++){
signalIndex["T1"].signal[i][0]=5;}
for(i=0;i<5;i++){
cout<<"TEST="<<testGrid.signal[i][0]<<"\n";}
for(i=0;i<5;i++){
cout<<"TEST2="<<signalIndex["T1"].signal[i][0]<<"\n";}
return 0;
}
void mapTest(std::map<string, signalGrid> &temp_map){
temp_map["T1"]=testGrid;
return;
}
signalGrid::signalGrid(){
int i,j;
for(i=0;i<20;i++){
for(j=0;j<200;j++){
signal[i][j]=0;}}
}

Yes, you are copying testGrid into the value corresponding to key "T1". Doing anything with that value will only modify the copy.
You could have a map<string, reference_wrapper<signalGrid>>, but I'm not exactly sure why you want the global testGrid variable in the first place. Why not get rid of testGrid and just deal with signalIndex["T1"]?

Related

C++ persistence of inserting local variable into a std::map by reference

I'm new to C++ and trying to understand a simple example of inserting a list of integers into a map.
#include <iostream>
#include <map>
#include <list>
using namespace std;
map<string, list<int>> m;
void insert(list<int>& list_to_insert)
{
m.insert({"ABC", list_to_insert});
}
void setup()
{
std::list<int> local_list = { 7, 5, 16, 8 };
insert(local_list);
}
int main()
{
setup();
cout << m["ABC"].size(); // PRINTS 4
}
As far as my understanding, local_list is a variable only known to the setup function. When I pass in a reference to the insert function, I expect it to work. However, at the end of setup, I expect local_list to be removed from the stack frame. However, in my main function, when I call size(), I see that it has in fact persisted throughout. I am not sure I understand how local_list gets persisted at the end of setup(). What is exactly happening here?
map<string, list<int>> m;
contains lists, not references to lists.
So your
m.insert({"ABC", list_to_insert});
will create a copy of the passed list.
PS: why-is-using-namespace-std-considered-bad-practice

Is there a simple way to implement it in C++?

I want to implement a function that can print out the value of one member variable (for example, 'aa') of struct ('Data') by it's name.
I try to use the macro definition as follows, but failed.
Is there a simple way to implement it?
#include <string>
#include <iostream>
using namespace std;
struct Data
{
int aa;
int bb;
int cc;
Data(): aa(1),bb(2),cc(3) {};
};
#define Param(a,b) a.##b
void Process(Data& data, const string& name)
{
cout << Param(data, name) << endl;
}
void main()
{
Data data;
Process(data, "aa");//I want print the value of Data.aa
Process(data, "bb");//I want print the value of Data.bb
Process(data, "cc");//I want print the value of Data.cc
}
This is not possible in C++.
This kind of usage is generally seen in scripting languages.
In C++ the variable names are constructed at compile time.
Your original code sample makes no sense to me because if you call Param(name) then the compiler has to know what instance of Data it has to use to determine the value of the member variable you want to get the value of (but I'm neither an expert using macros nor do I like them very much).
I tried to solve your problem using the following approach:
struct Data
{
int aa;
};
#define GetMemberValue(d, n) d.##n
int main()
{
Data d;
d.aa = 3;
int i = GetMemberValue(d, aa);
}
At least this approach returns the right result in this case.
Another thing is that you stated that you cannot call the member variables directly i.e. data.aa so you might run into the same issue using the macro. It's just a guess as I don't know the original code you're using.

how to initialise objects in a <list> and interate them in c++? Are they randomely stored?

I am new to c++ STL and am learning from ebooks and online sources. I wanted to create a list of objects, initialise them using ::interator and list.insert() and finally display the values stored in each object.
Here is the code:
#include <iostream>
#include <list>
#include <algorithm>
#define MAX 50
using namespace std;
class numbers{
int a;
int b;
int c;
int sumvar;
int sum()
{
return(sumvar=a+b+c);
}
public:
numbers(int a,int b,int c)
{
this->a=a;
this->b=b;
this->c=c;
}
void display()
{
cout<<a<<endl<<b<<endl<<c<<endl<<endl;
}
};
int main()
{
list<numbers> listofobjects;
list<numbers>::iterator it=listofobjects.begin();
for(int i=1;i<MAX-1;i++)
{
int j=i*21-4;
int k=i*j/7;
numbers *temp = new numbers(i,j,k); //i went through a two step initialise
numbers n=*temp;
listofobjects.insert(it,n);
it++;
}
for(it=listofobjects.begin();it!=listofobjects.end();it++)
{
it->display();
}
}
So I have 2 questions:
1) Did I initialise objects correctly?
2) When I ran the program, the program output started from 32. Shouldn't it start from 1?
No you did not initialize the list correctly. Your code leaks memory.
Your code:
1) Allocates a new instance of the numbers class using new.
2) Makes a copy of the instantiated object
3) Inserts the copy object into the std::list.
So, the new-ed object gets leaked. The only thing you needed to do was:
listofobjects.insert(it, numbers(i, j, k));
Now, as far as the reason why the order was wrong, it's because of a related reason -- the iterator for the insert position is not being incremented correctly. Your insertion should be:
it = ++listofobjects.insert(it, numbers(i, j, k));

End process error code -1 if acess to string field of structure

#include <cstdlib>
#include <string>
#include <iostream>
#define S 10
using namespace std;
struct List
{
string name;
bool male;
int year;
string addr;
string diag;
bool hosp;
};
main()
{
struct List *l=NULL;
int n=0;
for(int i=0;i<10000;i++)
{
if(!(n%S))
{
l=(List*)realloc(l,(n/S+1)*S*sizeof(struct List));
cout<<"realloc ok\n";
};
l[n].male=rand()%2;
l[n].year=1900+rand()%100;
l[n].hosp=rand()%2;
//!l[n].name="abc";
n++;
cout<<l[rand()%n].male<<" "<<l[rand()%n].year<<" "<<l[rand()%n].hosp<<endl;
}
}
If l[n].name="abc" remarked then program works fine.
If i try put string value to this field the programm compiled without warnings nay, but crash with error code -1 after first realloc.
Any way to solve it?
Since your structure is non-trivial - it contains members of class type, std::string, which need to be initialised by calling their constructors - you can't simply allocate raw memory and pretend that contains a valid object.
The simplest solution is to use a type-aware dynamic array
std::vector<List> l;
which can be resized, perserving its contents, with
l.resize((n/S+1)*S);
Tip! Using "new" operator to allocate this structure will automatically create string object for each field.
List *l=new struct List[S];
It fix this issue, l[n].name="abc" will works, but it not implements reallocation functional.

Passing a vector to constructor

Iam new in C++ and iam trying to implement classes into my program. I have done similar program in java. But iam struggling to implement classes in c++. I want to pass a vector with strings from main to a class called Search.I can pass a vector either by value or reference. Iam using a vector * which means get vector address.This is what i was told. Iam not sure how i should refer to it. I am sure there are more mistakes in my code. Could please someone help me or explain me how to initialize vector in constructor and how to add a value so I can use the vector in the menthod?? Iam using Visual Studio PRO 2010. Many thanks for replies.
Search.h
// pragma once
#include "std_lib_facilities.h"
#include <vector>
class Search
{
public:
Search();
Search(int dd, int mm, int year,vector<string>* dat);
vector<string> get_result ();
~Search(void);
private:
int d;
int m;
int y;
vector<string> data;
};
Search.cpp
#include "Search.h"
#include <vector>
#include "std_lib_facilities.h"
Search::Search()
:d(1), m(1), y(2000), data(){} //data() is the vector but iam not sure if ihave set the value corectly
Search::Search(int dd, int mm, int year,vector<string>*dat)
:d(dd),m(mm),y(year), data(dat){}//no instance of constructor matches the construcor list -- this is the error iam getting
//iam trying to initiliaze the varibale data of type vector.But i dont know how to do it.
Search::~Search(void)
{
}
vector<string> Search::get_result () {// implementation where i need to use the data stored in a vector
}
//main program
#include "std_lib_facilities.h"
#include <string>
#include <sstream>
#include <stdio.h>
#include "Search.h"
#include <vector>
int main(){
int day, month, year; //iam gonna ask user to input these
day=20;
month=12;
year=2014;
vector<string>flight_info;
ifstream inputFile("flight.txt");
// test file open
if (inputFile) {
string value;
// read the elements in the file into a vector
while ( inputFile >> value ) {
flight_info.push_back(value);//this is the vector i want to pass to class Search
}
}
Search search(day,month,year,flight_info)
//this where i want to create object of Search class but iam gettin error -no instance of constructor matches the `enter code here`construcor list.
}
This defines a vector:
vector<string>flight_info;
This defined a vector member variable:
vector<string> data;
This invoke a constructor by passing the vector to it:
Search search(day,month,year,flight_info)
But this constructor expects a pointer to a vector!
Search(int dd, int mm, int year,vector<string>* dat);
You don't need to pass any of the standard containers around by pointer (and you're probably doing something wrong if you find yourself trying to).
You can rewrite your constructor to be Search(int dd, int mm, int year,vector<string> dat) to resolve your error. You only need to change the prototype of your constructor, because data(dat) will already correctly construct the member vector.