I switched from c to c recently and just can't figure out what I'm doing wrong here. I would like to access and set the member of a map via another function.
Here is my example which you can just copy to cpp.sh or so if you like
#include <iostream>
#include <map>
using namespace std;
struct test{
int i;
int j;
};
void addValues(test* val){
if (val == NULL){
val = new test();
cout<<"new";
}
val->i = 10;
val->j = 12;
}
void printVal(test* val){
cout<<"finish " << val->i << " " << val->j;
}
int main()
{
map<string, test*> bla = {{"test1",NULL}};
addValues(bla.at("test1"));
printVal(bla.at("test1"));
return 0;
}
code from my project is a little bit more complex but it's basically this problem. I created a test in addValues() and have not deleted it. Why am I not able to print this value in printVal()? What am I missing?
Thanks in advance!
CodePudding user response:
Parameters are passed by value. Pointers are no exception to that. Your addValues
modifies a local copy of the pointer when a nullptr
is passed. Modifying that local copy does not affect the pointer in the map. Pass the pointer by reference:
void addValues(test*& val){
if (val == nullptr){
val = new test();
cout<<"new";
}
val->i = 10;
val->j = 12;
}
Or better yet, do not use raw pointers in the first place. Moreover, consider to write a constructor that initializes the members of test
instead of relying on the caller to initialize them.
CodePudding user response:
Example :
#include <iostream>
#include <map>
//using namespace std; NO teach yourself not to do this.
struct test
{
int i = 0; // <== in c you can initialize values of structs
int j = 0;
};
// this instead of printVal
std::ostream& operator<<(std::ostream& os, const test& t)
{
os << "i = " << t.i << ", j = " << t.j << "\n";
return os;
}
int main()
{
std::map<std::string, test> map =
{
{"test1",{1,1}},
{"test2",{2,2}},
};
// loop over all entries in the map
// range based for loop.
// each entry in the map is a key,value pair (not they key, not the value but a pair)
// https://en.cppreference.com/w/cpp/language/range-for
std::cout << "range based for over keyvalue pairs\n";
for (const auto& kv : map)
{
// note kv.second is where we use operator<< from earlier.
std::cout << "Key : " << kv.first << ", value : " << kv.second << "\n";
}
std::cout << "\n";
// structured bindings make code more readable
// https://en.cppreference.com/w/cpp/language/structured_binding
std::cout << "range based for using structured bindings \n";
for (const auto& [key, value] : map)
{
std::cout << "Key : " << key << ", value : " << value <<"\n";
}
std::cout << "\n";
return 0;
}