Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Debug Assertion Failure!

This thread is locked; no one can reply to it. rss feed Print
Debug Assertion Failure!
Onewing
Member #6,152
August 2005
avatar

Here's another question for ya, while I'm waiting to figure out this one.

Anyway, when I run my newest program (ChristmasHack title) as Debug, I get a Debug Assertion Failure when closing the program. This only occurs when my wrap text function is called (when talking to an NPC). If I run the program in Release, the problem doesn't exist.

I reget doing this, but here's the text wrapping function. Keep in mind, I've done this entire game in the hack mindset, even long after CH finished.

1void CBOX::wrap_text(BITMAP *bDisplay)
2{
3 int char_size = 8, line = 0, iIndex = 0, check;
4 char *cSave;
5 char cTransfer[1000];
6 char *cParse;
7 bool break_at_check = false;
8 int wrap_boundary = 0;
9
10 unsigned int width = dw - 10;
11 
12 if(cname != NULL)
13 {
14 textprintf_ex(bDisplay, font, x + 5+1, y + 5 + 1 + line, BLACK, -1, cname);
15 textprintf_ex(bDisplay, font, x + 5, y + 5 + line, YELLOW, -1, cname);
16 }
17
18 cParse = new char[strlen(ctext) + 1];
19 strcpy(cParse, ctext);
20
21
22 line += 15;
23
24 //textprintf(bText, oFont, bImage->w + 10, bImage->h + 10, -1, cText);
25 while((strlen(cParse) - wrap_boundary) * char_size > width && line < 80)
26 {
27 iIndex = width / char_size - 1;
28 // Find a space to break on
29 while(iIndex > 0 && cParse[iIndex] != ' ')
30 iIndex--;
31 if(iIndex <= 0) break;
32 //Now that we know where we are going to break, search for forced line breaks
33 for(int iCheck = 0; iCheck < iIndex; iCheck++)
34 {
35 if(iCheck < (strlen(cParse) - wrap_boundary) && iCheck + 1 < (strlen(cParse) - 1) && cParse[iCheck] == '\\' && cParse[iCheck+1] == 'n')
36 {
37 check = iCheck;
38 break_at_check = true;
39 }
40 }
41 
42 if(!break_at_check)
43 {
44 cSave = new char[strlen(cParse + iIndex + 1)+1];
45 strcpy(cSave, cParse + iIndex + 1);
46 cParse[iIndex] = '\0';
47 strcpy(cTransfer, cParse);
48 delete [] cParse;
49 cParse = cSave;
50 }
51 else
52 {
53 cSave = new char[strlen(cParse + check + 2)+1];
54 strcpy(cSave, cParse + check + 2);
55 cParse[check] = '\0';
56 strcpy(cTransfer, cParse);
57 delete [] cParse;
58 cParse = cSave;
59 }
60 check = 0;
61 break_at_check = false;
62 draw_text(bDisplay,line,cTransfer);
63 line += 10;
64 }
65
66 if(line < 80)
67 {
68 more = false;
69 strcpy(cTransfer, cParse);
70 draw_text(bDisplay,line,cTransfer);
71 }
72 else
73 {
74 more = true;
75 strcpy(cOld, cParse);
76 }
77
78 delete [] cParse;
79}

------------
Solo-Games.org | My Tech Blog: The Digital Helm

Kris Asick
Member #1,424
July 2001

I believe anywhere where you have the following fragments of code is bugged:

(cSave, cParse + iIndex + 1)
(cSave, cParse + check + 2)

...because the + operator is concatenating iIndex, check, 1 and 2 onto the cParse string when taking the length with strlen(), or when copying it to cSave with strcpy(), which I don't think is exactly what you're aiming for and I don't rightly know what will happen in memory when you do something like that.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Onewing
Member #6,152
August 2005
avatar

Quote:

because the + operator is concatenating

Since cParse is a pointer, I thought the + operator would move the address location of cParse. The output is exactly as I want, but when closing the program in Debug mode, it gives me that error.

------------
Solo-Games.org | My Tech Blog: The Digital Helm

Kris Asick
Member #1,424
July 2001

Ah, you're right, it does move the pointer. Duh. ::)

Something doesn't feel right when I look at that code. I'll figure it out...

EDIT:

This might be causing the problem...

  iIndex = width / char_size - 1;
  // Find a space to break on
  while(iIndex > 0 && cParse[iIndex] != ' ')
    iIndex--;

You see, width and char_size never change, so every time you start your loop you're checking iIndex number of characters beyond the current position within cParse, which may or may not be beyond the allocated memory for that variable.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Onewing
Member #6,152
August 2005
avatar

Quote:

Something doesn't feel right when I look at that code.

Probably because it's dang fugly. :D

Quote:

You see, width and char_size never change, so every time you start your loop you're checking iIndex number of characters beyond the current position within cParse

That shouldn't be the case. Because,

while((strlen(cParse) - wrap_boundary) * char_size > width && line < 80)
Now, the wrap_boundary does nothing (I set it to 0, I'm sure I had a purpose for it earlier). char_size was basically going to be a variable that figured out the width of the chars for the given font. In this case, I just set it 8 since I'm using the allegro standard font. So, strlen(cParse) * char_size figures out how much pixel width the text is going to take up horizontally and width is the pixel width of the box the text is being fit into. If it is bigger, then we need to do some chopping.

Thus, "iIndex = width / char_size - 1;" won't even occur unless "width / char_size" is within cParse's memory allocation.

Does that make sense? This is probably an overcomplicated way of wrapping text. :-/

------------
Solo-Games.org | My Tech Blog: The Digital Helm

Kris Asick
Member #1,424
July 2001

Yeah, that makes sense...

Well, I'm out of ideas. I suggest you try commenting the whole thing out, then slowly uncomment pieces of the code until the problem appears. Then you'll know where your memory leak is occurring, because it almost HAS to be a memory leak...

The only other thing I can think of, but am not sure about, is that it might be related to your method of pointer movement with cSave and cParse.

An assertion failure is a logic error where something that shouldn't happen does. Since you're not manually asserting anything it's something being handled automatically, which is almost certainly a memory issue.

If the routine works properly with debugging off then I would say the problem has something to do with places you've used strcpy(), or with the way you're allocating and deallocating your pointers, and that it's related to stuff being left behind since the stuff that's actively being used by the routine is fine.

--- Kris Asick (Gemini)
--- http://www.pixelships.com

--- Kris Asick (Gemini)
--- http://www.pixelships.com

Go to: