Pointers as lookup values in maps.

closed account (Sw07fSEw)
I'm trying to write a program that has a list of magicians along with dates of availability for each magician. For simplicity's sake, each of the magicians are available on the same dates. I want to search for magicians in a map using the magician name as the key to find a pointer, or an array containing a list of dates. Each magician needs their own pointer or array because I don't want Magician A being booked on date A, indirectly causing Magicians B & C to also be booked on date A. I want to copy values from the base array of holidays to a new array or pointer for each magician.

There's a logic error that I'm stuck on in my code. In the code below, I choose to hard code line 17 and set the value pointed to by p_holidays equal to the value of holidays.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <map>
#include <array>
using namespace std;

void setMagicianAvailability(string holidays[3], string magicianNames[3]){  
	string *p_holidays[3]; // array of 3 pointers, each pointer points to an array of holidays for each magician
	
	map<string, string*> magicians; // map of magician availability. The key is the magician name. value is a pointer to the array of holidays.
	map<string, string*>::iterator itr = magicians.begin();
	
	for(int i = 0; i < 3; i++){
		string magician_name = magicianNames[i]; // set the magician name as the key for the map
		p_holidays[i] = new string; 
		cout << "The address the new pointer is pointing to is: " << p_holidays[i] << endl; // visual evidence of the new pointer
        
        p_holidays[0][0] = holidays[1]; // 1st element pointed to by the 1st pointer takes the same value as the 2nd element in holidays[].
        
        magicians.insert(itr, pair <string, string*> (magician_name, p_holidays[i])); // add the magician name and the pointer to the array of holidays
	}
	cout << magicians["Magician_0"][0] << endl; // verify that the 1st holiday element in the 1st element of the map has been updated. 
}

int main(){
	string holidays[3] = {"Christmas", "Thanksgiving", "Easter"}; 
	string magicianNames[3] = {"Magician_0", "Magician_1", "Magician_2"};
	
	setMagicianAvailability(holidays, magicianNames);
		
	return 0;
}




I want use some sort of for loop to set the values at equal to each other. Logically, I'm thinking something like this:
1
2
3
4
5
6
7
8
9
10
 for(int i = 0; i < 3; i++){
		string magician_name = magicianNames[i]; // set the magician name as the key for the map
		p_holidays[i] = new string; 
		cout << "The address the new pointer is pointing to is: " << p_holidays[i] << endl;
		
		for(int j = 0; j < 3; j++){
		    p_holidays[i][j] = holidays[j];
		}
		magicians.insert(itr, pair <string, string*> (magician_name, p_holidays[i]));
	}


When I use the for loop instead of hard coding it, the program still compiles but crashes during run time because it. I can't figure out why.
Last edited on
Hmm,
1
2
3
4
5
string holidays[3]; // holidays[1] is a std::string
string * p_holidays[3]; // three pointers
p_holidays[i] = new string;  // each pointer points to one string object, not to array of strings

p_holidays[0][0] = holidays[1]; // ok. Copy string into the one and only string pointed to by p_holidays[0] 


There can beis only one:
1
2
3
4
5
for( int i = 0; i < 3; ++i ) {
  p_holidays[i] = new string; 
  *(p_holidays[i]) = holidays[i];
  // use p_holidays[i]
}



Last edited on
On your second snippet, it looks like you meant to do p_holidays[i] = new string[3];. Note that you don't need to use insert(). You could just do magicians[magicianNames[i]] = p_holidays[i];.
Why not just store the dates as the value type in maps rather than the pointer?

Better, you're already using std::map, so why not std::vector?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <map>
#include <string>
#include <vector>

using availability_type = std::map<std::string, std::vector<std::string>>;

availability_type generateAvailability(const std::vector<std::string>& holidays, 
                                       const std::vector<std::string>& magicians)
{
    availability_type availability;
    for (auto& magician : magicians)
        availability[magician] = holidays;

    return availability;
}

int main() {
    auto availability = generateAvailability({ "Christmas", "Thanksgiving", "Easter" },
                                             {"Magician_0", "Magician_1", "Magician_2" });

    for (auto & entry : availability)
    {
        std::cout << entry.first << " is available\n";
        for (auto & date : entry.second)
            std::cout << '\t' << date << '\n';
    }
}
Topic archived. No new replies allowed.