(Link to AcmlmWiki) Offline: thank ||bass
Register | Login
Views: 13,040,846
Main | Memberlist | Active users | Calendar | Chat | Online users
Ranks | FAQ | ACS | Stats | Color Chart | Search | Photo album
05-20-24 02:27 PM
0 users currently in Programming.
Acmlm's Board - I3 Archive - Programming - Realloc() fails for some reason New poll | |
Add to favorites | Next newer thread | Next older thread
User Post
HyperHacker

Star Mario
Finally being paid to code in VB! If only I still enjoyed that. <_<
Wii #7182 6487 4198 1828


 





Since: 11-18-05
From: Canada, w00t!
My computer's specs, if anyone gives a damn.
STOP TRUNCATING THIS >8^(

Last post: 6301 days
Last view: 6301 days
Posted on 12-12-05 01:41 AM Link | Quote
One of those fun bugs that makes no sense whatsoever.

NumTags++;
printf("realloc: %d x %d = %d\n",sizeof(XMLTag), NumTags, sizeof(XMLTag) * NumTags);
Tag = (XMLTag*)realloc((void*)Tag,sizeof(XMLTag) * NumTags);
if(!Tag)
{
SetError("Out of memory");
return false;
}


You can probably see that what this is supposed to do is allocate enough memory to hold NumTags XMLTag structures. However, for some reason it's failing:

Init
Parse
Alloc succeeded
1, 3: Tag '' (#0)
realloc: 52 x 1 = 52
End of tag ''
2, 8: Tag 'scene' (#1)
realloc: 52 x 2 = 104
End of tag 'scene'
3, 12: Tag 'textures' (#2)
realloc: 52 x 3 = 156
Parse error: Line 3, Col 12: Out of memory


It's only trying to allocate 156 bytes, but it fails. However, I added this above:
BYTE* blah = NULL;
for(int i=1;i<2048;i += 10)
{
blah = (BYTE*)realloc((void*)blah,i * sizeof(BYTE));
if(!blah)
{
printf("Failed at %d\n",i);
break;
}
}
if(blah) printf("Alloc succeeded\n");
free(blah);


This works just fine, so obviously there's at least 2K available.
Cellar Dweller +

Red Koopa









Since: 11-18-05
From: Arkansas

Last post: 6310 days
Last view: 6301 days
Posted on 12-12-05 03:44 AM Link | Quote
Exactly how sure are you that your program is not writing outside of allocated memory? If it is writing outside of allocated memory, it could be corrupting the heap and causing memory allocation functions to fail.
MathOnNapkins

1100

In SPC700 HELL


 





Since: 11-18-05

Last post: 6300 days
Last view: 6300 days
Posted on 12-12-05 07:40 AM Link | Quote
I've used realloc() a lot over the past few days.

First of all, make sure you pass it a pointer that was previously allocated by malloc( ) or calloc( ), etc.

Next, realloc can fail sometimes b/c of the way memory is allocated on your system. Is it windows 98? I know I had to put:

_set_sbh_threshold(0);

at the beginning of one of my programs to keep realloc from acting up.

Thirdly, I think you may be confused as to the proper size of your Tag pointer. An actual XMLTag structure might be pretty large, potentially. Am I right? Because I don't know the actual size of XMLTag structures. I think you are allocating too much memory by using sizeof(XMLTag) in your third line. I think it should be sizeof(XMLTag*) instead. That would mean you are dynamically allocating a list of pointers to (NumTags) many different XMLTags. Am I right about that? If that was your goal then make that modification and see how it runs.

Alternately, you could be allocating all your XMLTag structures together in a linear buffer maybe? But that is sort of a counter intuitive way of going about it, imo. It would also require more hassle in coding such a buffer.

If none of these ideas work I'm not sure what else to say except look up documentation on realloc and look at the number of reasons it can fail. There are probably a lot..
HyperHacker

Star Mario
Finally being paid to code in VB! If only I still enjoyed that. <_<
Wii #7182 6487 4198 1828


 





Since: 11-18-05
From: Canada, w00t!
My computer's specs, if anyone gives a damn.
STOP TRUNCATING THIS >8^(

Last post: 6301 days
Last view: 6301 days
Posted on 12-12-05 05:16 PM Link | Quote
It's XP, which has never given me any memory problems before (except with video memory ). I think you're probably right about using XMLTag* there, now that I look at it again. *tinkers a bit*

Yeah, I think it's writing outside of the array. Tsk tsk.

BTW, you can pass realloc() a NULL pointer; it'll just act like malloc().

[edit] Yep. A completely different part of the code was writing wrong (Tag[T].Attrib[i] should have been Tag[T].Attrib[i].Name). Fixing it was surprisingly simple: I just went through each call to realloc(), one at a time, and changed it to grab an extra 256 bytes. Once I changed the one that was being written wrong, the extra bytes made up for the bug and thus things ran better (it still crashed, but ran a lot longer). That's how I knew which array was being written wrong, and from there it was a snap to figure out where.

So yeah, yay me or something.


(edited by HyperHacker on 12-12-05 11:15 PM)
(edited by HyperHacker on 12-12-05 11:16 PM)
HyperHacker

Star Mario
Finally being paid to code in VB! If only I still enjoyed that. <_<
Wii #7182 6487 4198 1828


 





Since: 11-18-05
From: Canada, w00t!
My computer's specs, if anyone gives a damn.
STOP TRUNCATING THIS >8^(

Last post: 6301 days
Last view: 6301 days
Posted on 12-15-05 04:10 AM Link | Quote
OK, here's another fun one. fp is a FILE* and a private member of a class. The class has an Open() method which opens a file (using fp = fopen()). It also has a Close() method, guess what it does? I create one instance of this class by declaring it in the header file of my program. I call Open(), do some stuff with it, la dee da, then I want to open a different file in another function, so I call Close()... it crashes at fclose(fp). fp is still the same value that it was after fopen(), and the file is still open (at least, I never closed it), but as soon as it tries to close the file the entire program just quits with no error message. Is there any possible reason besides stack/memory corruption for this to happen? I already debugged the hell out of all the allocating routines.

Code follows:
class XMLReader
{
private:
[...]
FILE* fp;


public:
[...]
void Init();
void Unload();
void Reset();
BOOL Open(char* F);
void Close();
[...]
};

BOOL XMLReader::Open(char* F)
{
DBG(printf("Opening file '%s'\n",F));
//Get the directory
int i, p = -1;
for(i=strlen(F);i>=0;i--)
{
if(F[i] == '\\')
{
p = i + 1;
break;
}
}

if(p >= 0)
{
if(p > sizeof(FileDir)) p = sizeof(FileDir);
strncpy(FileDir,F,p);
}
else
sprintf(FileDir,".\\");
DBG(printf("File directory is '%s'\n",FileDir));

fp = fopen(F,"rb");
if(fp)
{
#if XML_DEBUG
fseek(fp,0,SEEK_END);
printf("File size is %d, ptr is 0x%08X\n",ftell(fp),fp);
rewind(fp);
#endif
return true;
}
return false;
}

void XMLReader::Close()
{
DBG(printf("Close file... "));
if(fp)
{
fclose(fp); <-- CRASH HAPPENS HERE when called from Unload() which is called from Reset()
DBG(printf("fclose... "));
fp = NULL;
}
DBG(printf("Done.\n"));
}

void XMLReader::Reset()
{
Unload();
Init();
DBG(printf("XML reader reset\n"));
}

void XMLReader::Init()
{
fp = NULL;
Line = 1;
Col = 1;
NumTags = 0;
FileStackPos = 0;
Tag = NULL;
}


void XMLReader::Unload()
{
Close();
for(int i=0;i<NumTags;i++)
{
DBG(printf("Free tag %d... ",i));
if(Tag[i].Content) free(Tag[i].Content);
if(Tag[i].Attrib) free(Tag[i].Attrib);
DBG(printf("Done.\n"));
}
DBG(printf("Free tag info... "));
free(Tag);
DBG(printf("Done.\n"));
}


[in main()]
if(!XML.Open("world_def.xml")) Die("Can't open world_def.xml\n");

[in another function]
XML.Reset();


*thwaps board* With the weird line break handling, I get to choose either having tabs in my <code> tags or not having every line double-spaced.


(edited by HyperHacker on 12-15-05 03:18 AM)
sloat



 





Since: 11-18-05
From: Delaware, US

Last post: 6404 days
Last view: 6404 days
Posted on 12-15-05 04:55 PM Link | Quote
don't you have to use "this" with everything...or am i stuck in php mode?

also, what exception is it giving you?
neotransotaku

Sledge Brother
Liberated from school...until MLK day








Since: 11-17-05
From: In Hearst Field Annex...

Last post: 6303 days
Last view: 6300 days
Posted on 12-15-05 07:06 PM Link | Quote
Is XML a global variable? Right now, the only thing I can think of is you aren't passing what you are think are passing to the function that calls XML.Reset()
HyperHacker

Star Mario
Finally being paid to code in VB! If only I still enjoyed that. <_<
Wii #7182 6487 4198 1828


 





Since: 11-18-05
From: Canada, w00t!
My computer's specs, if anyone gives a damn.
STOP TRUNCATING THIS >8^(

Last post: 6301 days
Last view: 6301 days
Posted on 12-15-05 07:22 PM Link | Quote
'this' is just a pointer to the class itself. I imagine you could use it, but you don't need to. XML is global. I don't think it's a problem with the function that calls Reset(), because the last output is "Close file...", right before the fclose() call (and the output right after fclose() doesn't occurr - removing it doesn't help either, so it's not the problem).

The annoying part is it doesn't give any exception. The program just closes and returns some random number.
HyperHacker

Star Mario
Finally being paid to code in VB! If only I still enjoyed that. <_<
Wii #7182 6487 4198 1828


 





Since: 11-18-05
From: Canada, w00t!
My computer's specs, if anyone gives a damn.
STOP TRUNCATING THIS >8^(

Last post: 6301 days
Last view: 6301 days
Posted on 12-18-05 08:02 AM Link | Quote
Pardon the bump but I did some more digging. First here's a disassembly of the problem function:
004026EE push ebp
004026EF mov ebp,esp
004026F1 sub esp,8
004026F4 mov dword ptr [esp],40C243h
004026FB call 0040A7A0 ;printf "close file..."
00402700 mov eax,dword ptr [ebp+8]
00402703 cmp dword ptr [eax+904h],0 ;if(fp)
0040270A je 00402736
0040270C mov eax,dword ptr [ebp+8]
0040270F mov eax,dword ptr [eax+904h] ;eax = file ptr
00402715 mov dword ptr [esp],eax
00402718 call 0040A740 ;fclose() - never passes this
0040271D mov dword ptr [esp],40C252h
00402724 call 0040A7A0 ;printf "fclose"
00402729 mov eax,dword ptr [ebp+8]
0040272C mov dword ptr [eax+904h],0
00402736 mov dword ptr [esp],40C026h
0040273D call 0040A7A0 ;printf "done"
00402742 leave
00402743 ret

;This gets called a lot - probably a generic API call handler
0040A740 jmp dword ptr ds:[4162F8h]


When run in the debugger, it does display an exception: Unhandled exception in sdl3dtest.exe (NTDLL.DLL): 0xC0000005: Access Violation. Finally, a stack dump:
ntdll.dll!wcsncpy+0x354
msvcrt.dll!free+0xc3
msvcrt.dll!wscanf+0x3857
msvcrt.dll!clearerr+0x8b
msvcrt.dll!fclose+0x37
sdl3dtest.exe+0x271d
sdl3dtest.exe+0x248b
sdl3dtest.exe+0x2577
sdl3dtest.exe+0x4feb
sdl3dtest.exe+0x4a3d
sdl3dtest.exe+0x92da
sdl3dtest.exe+0x11e7
sdl3dtest.exe+0x1238
kernel32.dll!RegisterWaitForInputIdle+0x49


I tested a bit, and the class is able to reset just fine in a small test program, so I imagine there's some sort of memory/stack corruption going on. The file pointer hasn't been changed. Don't hesitate to ask if you need more info.

[edit] I did some testing, and found interesting results... if you just pass some arbitrary pointer to fclose(), it crashes just like this does (access violation and all), but it only gets to msvcrt.dll!fclose+0x37 instead of ntdll.dll!wcsncpy+0x354, and actually shows the 'fatal error, close or debug' message. More interesting is that if you open a file, then try to close it twice, nothing bad happens. I don't think this really means anything, though, because I'm positive the pointer is correct... I even looked at the memory in the debugger and made sure of it. I wonder if some small problem in my code could have triggered some large problem in Windows'?

[edit 2] Hah! Figured out why it wasn't showing any error... I forgot SDL has a built-in exception handler, which apparently decided to just kill the program. With that off, I do get an error: The instruction at "0x7c910de3" referenced memory at "0x7473654c". The memory could not be "read".


(edited by HyperHacker on 12-18-05 07:05 PM)
(edited by HyperHacker on 12-18-05 10:40 PM)
sloat



 





Since: 11-18-05
From: Delaware, US

Last post: 6404 days
Last view: 6404 days
Posted on 12-19-05 02:00 AM Link | Quote
Originally posted by HyperHacker
[edit 2] Hah! Figured out why it wasn't showing any error... I forgot SDL has a built-in exception handler, which apparently decided to just kill the program. With that off, I do get an error: The instruction at "0x7c910de3" referenced memory at "0x7473654c". The memory could not be "read".


It looks like 0x7473654C is a string that's getting dereferenced too many times, or in this case, probably overwriting your file pointer. If you convert it to ascii you get "tseL". But remember that an x86 processor always reads addresses from low to high, so the actual string that it thinks is a pointer is "Lest". I dunno if that has any significance to you, but to me it would be a starting point.
HyperHacker

Star Mario
Finally being paid to code in VB! If only I still enjoyed that. <_<
Wii #7182 6487 4198 1828


 





Since: 11-18-05
From: Canada, w00t!
My computer's specs, if anyone gives a damn.
STOP TRUNCATING THIS >8^(

Last post: 6301 days
Last view: 6301 days
Posted on 12-19-05 06:22 AM Link | Quote
Yeah, I checked that out, but no such strings were anywhere to be found. It actually turned out I'd declared something as an array of pointers to structs when it should have been an array of structs.

Also, I managed to cause a BSOD with an IRQL_NOT_LESS_OR_EQUAL error by adding some Beep()s around another area that was segfaulting (trying to read from address 0).

BTW, if you have any idea how, write your own exception handler (look at SetUnhandledExceptionFilter). It makes things so freaking much easier.


(edited by HyperHacker on 12-19-05 05:22 AM)
MisterJones

Tooky








Since: 12-08-05
From: Mexico

Last post: 6390 days
Last view: 6326 days
Posted on 12-19-05 11:54 AM Link | Quote
Closing a file twice with fclose() should not be a problem:

Originally posted by "Standard Library"

fclose
Syntax

#include

int fclose(FILE *file);

Description

This function closes the given file.

Return Value

Zero on success, else EOF.

Portability

ANSI/ISO C C89; C99



Tried to eval result? Have you already tried using a breakpoint there and go step by step checking?

Would be a little stupid from me to say to use stream classes rather than FILE pointers?

try/catch already?


(edited by MisterJones on 12-19-05 10:56 AM)
HyperHacker

Star Mario
Finally being paid to code in VB! If only I still enjoyed that. <_<
Wii #7182 6487 4198 1828


 





Since: 11-18-05
From: Canada, w00t!
My computer's specs, if anyone gives a damn.
STOP TRUNCATING THIS >8^(

Last post: 6301 days
Last view: 6301 days
Posted on 12-23-05 11:12 AM Link | Quote
Yeah, I fixed it already.
Originally posted by HyperHacker
It actually turned out I'd declared something as an array of pointers to structs when it should have been an array of structs.


Memory corruption causes really weird problems.
Add to favorites | Next newer thread | Next older thread
Acmlm's Board - I3 Archive - Programming - Realloc() fails for some reason |


ABII

Acmlmboard 1.92.999, 9/17/2006
©2000-2006 Acmlm, Emuz, Blades, Xkeeper

Page rendered in 0.010 seconds; used 431.65 kB (max 544.38 kB)