Character arrays and scope

Hello, I'm testing a program that will create an array of objects (Equipment) from values parsed from a text file. Equipment objects have 6 integer values and a name, which is a character array (char * name). I have about 99% of the program working, but somewhere in the course of things the name field turns into jibberish. Since there are a number of files involved here (main.cpp, testsuite.cpp, fileio.cpp, equipment.cpp) I'll explain what's happening and post the relevant bits.

main calls a method in testsuite, which calls a method in fileio, passing it an array of Equipment objects. fileio fills in each entry of the array. testsuite prints the value of each entry's fields to the console. Each of the 6 integers for each Equipment object is parsed and saved properly, and each name is parsed properly, but by the time it gets to the output in testsuite it is nonsense characters.

By debugging I have found that the name field is the correct value up until the end of the method in fileio, but when that method finishes executing the name field reverts to jibberish. Following are the bits of code I imagine are relevant:

Fileio.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void Fileio::buildEquip(Equipment *equipdb){
	int pos = 0;
	ifstream eqfile("equipment.txt", ios::in);
	while(pos < EQUIPMENT_DB_SIZE){
		char name[EQUIPMENT_NAME_MAX];
		eqfile.getline(name, EQUIPMENT_NAME_MAX, '`');
                //parsing integer values here, left out for brevity
		equipdb[pos].setName(name);
		//setting integer values here, left out for brevity
		pos++;

	}

}

Equipment.cpp:
1
2
3
4
5
6
7
		char * Equipment::getName(){
			return name;
		}
		bool Equipment::setName(char * n){
			name = n;
			return true;
		}


Is this because the value pointed to by the name pointer within the while loop only exists while the loop is executing? If so, how/where should I declare the variable so that the Equipment object maintains the proper value after the buildEquip method finishes?

Update: I fixed this problem by using string objects instead of c-strings. However, it would still be good to know if there is a simple way to do this using c-strings without important information falling out of scope.
Last edited on
things that are declared within the scope of some execution block and are not created on the free store get destroyed after they leave scope.

you could use the new keyword.

1
2
3
char* name = new char[EQUIPMENT_NAME_MAX];
...
equipdb[pos].setName(name);  


But its better to use std::string because all that functionality (like cleanup, appending strings and the like) that you would need to include in your code is already built in within the implementation. plus its written by a bunch of much smarter people then you. ;)
Update: I fixed this problem by using string objects instead of c-strings. However, it would still be good to know if there is a simple way to do this using c-strings without important information falling out of scope.


You could've made name an array of char and copied the data pointed to by the parameter in setName. Of course, you'd have to make sure it was of a large enough size to do so. You could also have let it as a pointer (or used a smart pointer) and allocated memory in setName to hold the data pointed to by the parameter. Of course, then you would also have to deallocate the memory when the object is destroyed and handle things like a second setName call without leaking memory. That's essentially what happens with std::string, but it's all done automatically by the class machinery.
Topic archived. No new replies allowed.