Struct pointer

1
2
3
4
5
6
struct ITEM
{
	string	Name;
	ITEM*	folder;
	int*	Variable;
}


1
2
3
4
5
6
7
8
9
10
ITEM AddFolder(std::string Name, int *Variable)
{
	ITEM tItem;
	tItem.Name = Name;
	tItem.Variable = Variable;

	VEC.push_back(tItem);

	return tItem;
}


1
2
3
4
5
6
7
8
9
ITEM AddItem(std::string Name, int *Variable, ITEM *folder)
{
	ITEM tItem;
	tItem.Name = Name;
	tItem.Variable = Variable;
	tItem.folder = folder;

	VEC.push_back(tItem);
}


1
2
3
4
5
6
ITEM FOLDER = AddFolder("Folder", &vFolder);
AddItem("Item", &vItem, &FOLDER);

if (VEC[i].folder)
{
	if (*VEC[i].folder->Variable) // crash here 


this is kind of how im trying to do this but it crashes.
im not sure why
Last edited on
do what? what crashes?
well im making a list thing

that has folders

i need to be able to read the folder info from the items

the folders work fine.

but when im using the items i get a crash reading the folders Variable
the Variable is a int

1 = folder open
0 = closed

i had everything working till i needed to read from the folders struct

if i change
 
if (*VEC[i].folder->Variable)

to
 
if (VEC[i].folder->Variable)

all my items are shown but closing an opening folders dont do anything
Last edited on
post your code please
Just looking at the code you have, AddFolder creates an ITEM. It does not set that ITEM's folder member to any reasonable value. This will be a source of problems.

AddItem promises to return a value. It does not.

If you're using a vector and storing the address of the ITEM objects which are elements in the vector, then that will also likely result in issues. When vectors need to increase size the elements are relocated in memory, invalidating pointers and iterators. Use a std::deque instead in that case.
Last edited on
it dont need to return anything since im reading from the vector

an in the vector i was checking if the item is a folder or a item.

if its a folder do the folder stuff.
if item i check if the folder tab is open by checking the folders Veriable thats linked to the item.

i still dont understand why i crash or get a null pointer when im setting it an checking if its null

like i said it works if i dont read it as a pointer but then it thinks all the folder tabs are open

also if i change my struct pointer in the items to the folders int var
then it works as it should
but problem is that i need to read more of the folders info then that

so it has to be with how im setting it or reading it
Last edited on
it dont need to return anything since im reading from the vector

It needs to return something, because you told the compiler it returns something.

i still dont understand why i crash or get a null pointer when im setting it an checking if its null

See notes above and supply more context. Your code is incomplete and reasoning about your incomplete code is not terribly productive.
oh my bad it was ment to be a void for AddItem typo

in AddFolder i set the ITEM to NULL
Last edited on
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
32
struct ITEM
{
	int		Type;
	string	Name;
	char**	Options;
	int		OptionsSize;
	int*	Variable;
	ITEM*	folder;
	
	vector<ITEM> Item;

	struct
	{
		int postion;
		int x;
		int y;
		int width;
		int height;
	}ItemPos, ItemOptionsPos;

	ITEM() :
		Type(0),
		Name(""),
		Options(NULL),
		OptionsSize(0),
		Variable(0),
		folder(NULL),
		Item(NULL),
		ItemPos({ 0, 0, 0, 0, 0 }),
		ItemOptionsPos({ 0, 0, 0, 0, 0 })
	{}
};


1
2
3
4
5
6
7
8
9
10
class cMenu
{
public:

	ITEM AddFolder(std::string txt, int *var, ITEM* folder = NULL);
	void AddItem(std::string txt, char **opt, int *var, ITEM *folder = NULL, int type = MENUITEM);
private:
	
	vector<ITEM> MENU;
}


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
32
33
34
35
36
ITEM cMenu::AddFolder(std::string Name, int *Variable, ITEM *folder)
{
	ITEM tMenu;
	tMenu.Type = MENUFOLDER;
	tMenu.Name = Name;
	tMenu.Options = new char*[] {"", ""};
	tMenu.OptionsSize = 2;
	tMenu.Variable = Variable;
	tMenu.folder = folder;

	MENU.push_back(tMenu);

	return tMenu;
}

void cMenu::AddItem(std::string Name, char **Options, int *Variable, ITEM *folder, int Type)
{
	ITEM tMenu;
	tMenu.Type = Type;
	tMenu.Name = Name;
	tMenu.Options = Options;

	int OptionsSize = 0;
	while (*Options != '\0')
	{
		OptionsSize++;
		Options++;
	}

	tMenu.OptionsSize = OptionsSize;
	tMenu.Variable = Variable;

	tMenu.folder = folder;

	MENU.push_back(tMenu);
}


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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
		for (unsigned int i = 0; i < MENU.size(); i++)//Iterate trough all of the menu items
		{
			if (MENU[i].Type == MENUFOLDER && !MENU[i].folder)
			{
					if (IsMouseOver(x, fItemPos, Width, 19))
					{
						curItemMouseOver = &MENU[i];
						Draw.FillRGBA(x - 1, fItemPos, 1, 19, RED(255));
						Draw.FillRGBA(x + Width, fItemPos, 1, 19, RED(255));
						sprintf(FolderText, "• %s", MENU[i].Name.c_str());
					}
					else
						sprintf(FolderText, "%s", MENU[i].Name.c_str());
					//==============================================================================================
					//Background rectangles
					Draw.FillRGBA(x, fItemPos, Width, 19, D3DCOLOR_ARGB(120, 255, 255, 255));
					//==============================================================================================

					//==============================================================================================
					//Draw teh text
					Draw.Text(FolderText, x + 3, fItemPos + 2, Left, 1, true, WHITE(255), BLACK(255));
					//Draw.Text((char *)MENU[i].opt[*MENU[i].var], x + Width - 3, fItemPos + 2, Right, 1, true, WHITE(255), BLACK(255));
					//==============================================================================================

					MENU[i].ItemPos = { i, x, fItemPos, Width, ItemHeight };

					fItemPos += ItemHeight;

					Height = fItemPos - MENU_Y;
			}

			if (MENU[i].Type == MENUITEM || MENU[i].folder)
			{
				if (*MENU[i].folder->Variable)
				{
					if (IsMouseOver(x, fItemPos, Width, 19))
					{
						curItemMouseOver = &MENU[i];
						Draw.FillRGBA(x - 1, fItemPos, 1, 19, RED(255));
						Draw.FillRGBA(x + Width, fItemPos, 1, 19, RED(255));
						sprintf(ItemText, "• %s", MENU[i].Name.c_str());
					}
					else
						sprintf(ItemText, "%s", MENU[i].Name.c_str());
					//==============================================================================================
					//Background rectangles
					Draw.FillRGBA(x, fItemPos, Width, 19, D3DCOLOR_ARGB(80, 230, 230, 230));
					//==============================================================================================

					//==============================================================================================
					//Draw teh text
					Draw.Text(ItemText, x + 3, fItemPos + 2, Left, 1, true, WHITE(255), BLACK(255));
					Draw.Text((char *)MENU[i].Options[*MENU[i].Variable], x + Width - 3, fItemPos + 2, Right, 1, true, WHITE(255), BLACK(255));
					//==============================================================================================

					MENU[i].ItemPos = { i, x, fItemPos, Width, ItemHeight };

					fItemPos += ItemHeight;

					Height = fItemPos - MENU_Y;

					//if (MENU[i].Type == MENUSUBFOLDER)
					///	ShowMenu(pDevice, x, y, MENU[i].Item);
				}
			}
		}


1
2
3
	ITEM FOLDER = Menu.AddFolder("FOLDER", &iFolder);

	Menu.AddItem("Item1", Item1Options, &iItem1, &FOLDER);
1
2
3
	ITEM FOLDER = Menu.AddFolder("FOLDER", &iFolder);

	Menu.AddItem("Item1", Item1Options, &iItem1, &FOLDER);


You assign a pointer to local variable. The question is: Does the variable FOLDER exist when you later access it with if (*VEC[i].folder->Variable)?

I suggest that AddFolder(...) returns a pointer to ITEM instead of a copy.
Since you are using C++11: Better use a std::unique_ptr or std::shared_ptr.

http://www.cplusplus.com/reference/memory/unique_ptr/?kw=unique_ptr
http://www.cplusplus.com/reference/memory/shared_ptr/?kw=shared_ptr

This will solve the scope problem.

[EDIT]
By the way if (*VEC[i].folder->Variable) will access the content of Variable not the pointer

Line 32: This is wrong: if (MENU[i].Type == MENUITEM || MENU[i].folder)
I'd think you mean: if (MENU[i].Type == MENUITEM && MENU[i].folder) // Note: &&
Last edited on
I changed the function to return a pointer
but problem now is that *MENU[i].folder->Variable is acting like it did before if i did MENU[i].folder->Variable its just showing everything now

Also it dont get deleted anywhere.

thanks never knew about unique_ptr and shared_ptr will have to have a look at them.

Thanks for the reply
Last edited on
Important is that you do not return a pointer to a local variable. Instead create the object with new.

And yes the ..._ptr will solve the delete dilemma

By the way: while (*Options != '\0')
probably doesn't do what you think it does. (*Options != '\0') is a pointer comparison [with 0]
oh ok right

 
while (*Options != '\0')

is my loop to count the amount of items in the char array till it hits NULL
Topic archived. No new replies allowed.