Go Back   CodeCall Programming Forum > Software Development > C and C++
Register Blogs Search Today's Posts Mark Forums Read

C and C++ C and C++ forum for discussing all forms of C except for C#. These languages are powerful low level languages used for creating Operating Systems, Device Drivers, compilers and much more.

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old 10-12-2009, 11:07 AM
Newbie
 
Join Date: Oct 2009
Posts: 4
kimbecause is an unknown quantity at this point
c stack problem with multi-dimensional character arrays?

Now that I have your attention

I am a first year uni student and had to make a c program for an assignment. Have run into problems though with pointers changing (mebe just breaking?) at a strange point where I should (read _should_ lol) have locked down all the random memory writes. I would normally just trawl forums / google looking for answer to something like this but feel here it is too ambiguous and strange to get something out of it. So here goes.

A bit of background: The program is a small 2d RPG that has a 40x40 map array and a 40x40 monsters / items array. It has a function GenerateMap that poplulates both these arrays at the start of the game. I then has the ability to go up and down levels via a trigger
that recalls GenerateMap with a different seed index.

It did originally work, but I changed the map access with the original being (simplified e.g.)

if (map[x][y] == 'g') //read
map[x][y] = 'x' //write

Like I said this worked fine but some parts of the map were obviously reading / writing outside the map. It worked, but badly. I changed it so that this became part of wrapper modules ReadMap() and WriteMap() that preformed error checking in the basic form

char ReadMap(map, x, y)
if (within bounds)
return map[x][y]

and the same for writing to the map. Now I don't have any problems with writing to strange areas of RAM and know that the rest of the program isn't going to be modified when writing to the map.

The problem is this:
void RunTests() is used to check among other things whether a map change is required. If it is it increases the map seed number and reruns GenerateMap(). This works out fine, and returns back to RunTests without error. Exiting out of RunTests however the pointer to monstersItems() is destroyed. Instead of eg 0x7fffa0df6520 it is changes to 0x7fffffffffff. Somehow the program stack is being destroyed from outside what is writeable. Now when ReadMap() or WriteMap() are run the XY values are ok but the pointer is outside of what the program can read and it segfaults. I have run kdbg all over
this program but have no idea what the problem is here.

So to recap

GameState()
//pointer to monstersitems is fine here
<do stuff>
RunTests()
//pointer points to wrong address
//next ReadMap() or WriteMap() segfaults as we are reading outside of program block.

RunTests()
if (need level change)
//pointer to monsters is fine here
GenerateMap(mapSeed + 1)
//pointer is still fine

I've included my full source for you to look at but appreciate the time it takes to identify with the code and find errors. Like I said I normally don't just go on forums and say "this is broke, how to fix lol" but in these extenuating circumstances I can't see my normal forum trawl helping much. If anyone could give some description of the problem itself so that I could research it would be greatly appreciated.

[edit] Also again some things may be done a bit strangely / badly. This is my first major c project, I'm still learning. feel free to tell me what is wrong and if you can be bother how / why it can be made better.

[edit] Gah sent production version with my full name / student number int it. Any way to delete? Ok got it.

[another edit] One dodgy way I though around this would be in GameState() to back up the pointer, run it, and copy back.

tmpPoint = &monstersItems;
RunTests;
&monstersItems = tmpPoint;

Is this possible? Would this work? I have no idea how I would code-wise go about this, but that's nothing half an hour on google wouldn't fix
Attached Files
File Type: c CIDR-003a.c (74.6 KB, 18 views)

Last edited by kimbecause; 10-12-2009 at 02:38 PM..
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2 (permalink)  
Old 10-12-2009, 01:09 PM
WingedPanther's Avatar
Super Moderator
 
Join Date: Jul 2006
Age: 36
Posts: 11,435
WingedPanther has much to be proud ofWingedPanther has much to be proud ofWingedPanther has much to be proud ofWingedPanther has much to be proud ofWingedPanther has much to be proud ofWingedPanther has much to be proud ofWingedPanther has much to be proud ofWingedPanther has much to be proud ofWingedPanther has much to be proud of
Re: c stack problem with multi-dimensional character arrays?

The real question is: WHERE does monsterItems get changed? Have you been able to use debugging statements to localize it more precisely? Have you run your code in a debugger?
__________________
CodeCall Blog | CodeCall Wiki | Shareware
Programming is a branch of mathematics.
My CodeCall Blog | My Personal Blog
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3 (permalink)  
Old 10-12-2009, 01:56 PM
Newbie
 
Join Date: Oct 2009
Posts: 4
kimbecause is an unknown quantity at this point
Re: c stack problem with multi-dimensional character arrays?

Thanks for the response. monstersItems[][] is moved around and changed a fair bit, but it's pointer is never modified. All reads and writes to these decayed arrays are bounds checked, so they are not writing over local stack data (as I said, I'm not sure how stack data is stored in RAM so i'm not sure if this is possible). To clarify,


//monstersItems[][] is passed into GameState as an array decayed to a pointer to it's first element.
GameState()
//pointer to monstersitems is fine here
<do stuff>
RunTests()
//pointer points to wrong address
//next ReadMap() or WriteMap() segfaults as we are reading outside of program memory block.

RunTests()
if (need level change)
//pointer to monsters is fine here
GenerateMap(mapSeed + 1)
//pointer is still fine

So the stack is definitely getting corrupted through the process of GenerateMap() before returning to GameState. I've confirmed this using kdbg (the kde linux debugger), but only know how to view the local stack data, not the total memory area, so don't know where / why data is being written.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4 (permalink)  
Old 10-12-2009, 02:31 PM
Newbie
 
Join Date: Oct 2009
Posts: 4
kimbecause is an unknown quantity at this point
Re: c stack problem with multi-dimensional character arrays?

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaah. So many hours.

I found a way in kdbg to watch stack information in real time. I looped through one line at a time watching the information for EnterGameState. Finally in a completely unrelated function (probably written at 2am. Its 2:30 am now btw) I found this:

Code:
short GetNextRoom(int *roomX, int *roomY, int roomBuffer[][2], int completedRooms[][2])
{
	/*	Function: GetNextRoom()
		Written: 01/09/09
		By: <me>
		Takes: roombuffer
		returns: x and y of next required room
		Requires: 
		Does: returns the x/y of the next viable room in the frameBuffer. Returns 1 if this is found.
	*/
	
	short tmpI;
	short output = 0;
	
	for (tmpI = 0; tmpI < 256; tmpI++)
	{
		if (roomBuffer[tmpI][0] != -1)
		{
			*roomX = roomBuffer[tmpI][0]; //update vars
			*roomY = roomBuffer[tmpI][1];
			if (TestCompleted(roomBuffer[tmpI][0], roomBuffer[tmpI][1], completedRooms) == 0) //final test to see if room has been done before
			{	tmpI = 300; } //break loop
			roomBuffer[tmpI][0] = -1; //tag this index for reuse

			output = 1; //generate return
		}
	}
	
	return output;
}
Of course after the final test to see if the room has been done before it changes the index in use, and then modifies it exactly 44 bytes after the end of the array. In m**********ing stack data.

Obviously when this module is run earlier in the stack it was editing goodness knows what in a way that wasn't crashing the program; moving it further into used memory messed it up.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5 (permalink)  
Old 10-12-2009, 09:29 PM
ZekeDragon's Avatar
Code Warrior
 
Join Date: Jul 2009
Location: Nowhere, Washington
Posts: 1,721
ZekeDragon is a name known to allZekeDragon is a name known to allZekeDragon is a name known to allZekeDragon is a name known to allZekeDragon is a name known to allZekeDragon is a name known to all
Send a message via AIM to ZekeDragon Send a message via MSN to ZekeDragon Send a message via Skype™ to ZekeDragon
Re: c stack problem with multi-dimensional character arrays?

It's always a seemingly unrelated problem. Welcome to serious programming.

Oh, also, I'd suggest you divide your program up into multiple files. Your file is already coming up on 2400 lines, and that should really be divided into multiple files. You'll have a much easier time managing each piece and seeing what's going on if you took some time out to refactor your code that way, placing relevant functions next to each other in different files. You've got more than big enough of a program to do that with!
__________________
On Hiatus...
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #6 (permalink)  
Old 10-12-2009, 11:24 PM
Newbie
 
Join Date: Oct 2009
Posts: 4
kimbecause is an unknown quantity at this point
Re: c stack problem with multi-dimensional character arrays?

Thanks, I will definitely look into this. There are some certain places where the code could be split. Quick! To the GoogleMobile (plays batman music).
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #7 (permalink)  
Old 10-12-2009, 11:56 PM
ZekeDragon's Avatar
Code Warrior
 
Join Date: Jul 2009
Location: Nowhere, Washington
Posts: 1,721
ZekeDragon is a name known to allZekeDragon is a name known to allZekeDragon is a name known to allZekeDragon is a name known to allZekeDragon is a name known to allZekeDragon is a name known to all
Send a message via AIM to ZekeDragon Send a message via MSN to ZekeDragon Send a message via Skype™ to ZekeDragon
Re: c stack problem with multi-dimensional character arrays?

'Tis the best place to find information, Google!

But here's a quick and easy convenience reference:

In order to write a program using multiple files, you'll need to employ source files and header files, and the distinction is that header files will be directly #included into your source files as necessary, whereas your source files will maintain the executable code and will be the partitions of your generated .o files. The name's of the .c source files aren't important, nor are the names of the header files, however convention states that .h header files should be named the same name as their according .c source files that contain the functions described in the header. A header will look like this:

Code:
#if !defined(MYHEADERNAME_H_INCLUDED)
#define MYHEADERNAME_H_INCLUDED

int myFunction(int, char**); /* Function prototype. */
/* Other function prototypes would also go in header files
   according to the .c source file's functions.
   You should also include struct's, typedefs, and necessary
   #define calls and macros in header files.               */

#endif
The according source file to the above header would look like so:
Code:
#include "myheadername.h"

int myFunction(int aNum, char** args)
{
    /* This is the actual function body that does the work. */
    return aNum;
}
In this manner you can attach the .c source files you've written by #including their according .h header files into other source files. Like so in main.c:

Code:
#include <stdio.h>
#include "myheadername.h"

int main(int argc, char* argv[])
{
    int retnum;
    retnum = myFunction(argc, argv);
    printf("%d", retnum);
    return 0;
}
And that's a quick and dirty tut on including other files!
__________________
On Hiatus...

Last edited by ZekeDragon; 10-13-2009 at 12:01 AM.. Reason: Whoop, not done!
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes


Similar Threads
Thread Thread Starter Forum Replies Last Post
C++ ADTs: Stacks and Queues Part 1: Using Arrays WingedPanther C Tutorials 9 11-15-2009 08:45 PM
Java Generics and the Stack chili5 Java Tutorials 3 07-20-2009 08:21 AM
PHP Arrays chili5 PHP Tutorials 7 05-22-2009 05:16 PM
stack problem: print after pop function george_ya C and C++ 1 04-07-2009 03:53 PM
Stacks chili5 Java Tutorials 5 03-07-2009 09:16 PM


All times are GMT -5. The time now is 09:27 AM.


vBulletin v3.8.0 ©2010, Jelsoft Enterprises Ltd.


no new posts

LinkBacks Enabled by vBSEO 3.1.0