home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #16 / NN_1992_16.iso / spool / comp / sys / mac / programm / 13020 < prev    next >
Encoding:
Internet Message Format  |  1992-07-25  |  6.7 KB

  1. Path: sparky!uunet!wupost!waikato.ac.nz!comp.vuw.ac.nz!actrix!Bruce.Hoult
  2. Newsgroups: comp.sys.mac.programmer
  3. Subject: Re: Parameter Types for GetIndString, ParamText, NewString, et al.
  4. Message-ID: <1992Jul25.121251.6284@actrix.gen.nz>
  5. From: Bruce.Hoult@bbs.actrix.gen.nz
  6. Date: Sat, 25 Jul 1992 12:12:51 GMT
  7. Sender: Bruce.Hoult@actrix.gen.nz (Bruce Hoult)
  8. References: <1992Jul25.002622.1@tesla.njit.edu>
  9. Organization: Actrix Information Exchange
  10. Lines: 166
  11.  
  12. In article <1992Jul25.002622.1@tesla.njit.edu> erh0362@tesla.njit.edu (Elliotte Rusty Harold) writes:
  13. >     Can anyone spot the problem in the following code?
  14.  
  15. Well, uh, just one or two.. :-)
  16.  
  17.  
  18. > It typically crashes 
  19. > at either the GetIndString, the ParamText, or the StopAlert call.  I suspect 
  20. > I'm not passing the proper type of argument to one of the toolbox calls (e.g. 
  21. > sending a Str255 where I should be passing a StringPtr or vice versa) but I've 
  22.  
  23. No, you're corrupting the heap.
  24.  
  25.  
  26. > tried this with many different combinations of variable 
  27. > type without success.  The various 
  28. > sample source I've looked at has been inconsistent on the type of argument 
  29. > passed to these toolbox calls, i.e. some pass strings and some pass StringPtr's.
  30.  
  31. Once you start mucking around behind the compiler's back by using *
  32. and & the declared types or variables matters not one bit -- it becomes
  33. *your* responsibility to know what you're doing.
  34.  
  35. Read the documentation.  Understand in particular where the Toolbox is
  36. going to return a value to you and make sure you're very sure about
  37. where it is going to write that information for you and that there is
  38. enough space for what it is going to write.
  39.  
  40.  
  41. > Do I need to allocate space for errorString (a Str255) or is it automatically 
  42. > allocated since errorString is really an array of 256 chars?  If I 
  43. > do need to allocate space, how?
  44.  
  45. No you don't, because it is a local variable.  You need to learn what
  46. a C compiler does with local variables -- where they are allocated
  47. space (on the stack) and when (allocated at function entry,
  48. deallocated at function exit).
  49.  
  50.  
  51. > Can I dispense with the StringHandle 
  52. > errorStringH  entirely and just use errorString and &errorString as necessary? 
  53. > All suggestions appreciated.  Problem function follows.
  54.  
  55. Yes.  Just look at the definition of GetIndString:
  56.  
  57. ---------
  58. PROCEDURE GetIndString(VAR theString: Str255;strListID: INTEGER;index: INTEGER);
  59. File {PInterfaces}ToolUtils.p
  60. Inside Macintosh reference: I-468
  61. Moves or purges memory.
  62. [Not in ROM]
  63.  
  64. GetIndString returns in theString a string in the string list that has the resource
  65. ID strListID. It reads the string list from the resource file if necessary, by calling
  66. the Resource Manager function GetResource('STR#',strListID). It returns the string
  67. specified by the index parameter, which can range from 1 to the number of strings in
  68. the list. If the resource cant be read or the index is out of range, the empty
  69. string is returned.
  70. ---------
  71.  
  72. This means that you have to somehow allocate enough space for a 255 character
  73. string, and then tell GetIndString where it is.  It could be a local variable
  74. (like your "errorString" or on the heap (like your errorStringH), as long
  75. as it's big enough.
  76.  
  77. Let's have a look at your code as it stands:
  78.  
  79. > Boolean IOCheck(OSErr errornumber) {
  80. >     Str255     errorString;
  81. >     StringHandle errorStringH;    
  82. >     if (errornumber != noErr) {
  83. >         errorStringH = NewString(&errorString);
  84.  
  85. Do you know what NewString does?  Let's look in TFM, shall we?
  86.  
  87. ----------
  88. FUNCTION NewString(theString: Str255): StringHandle;
  89.     INLINE $A906;
  90. File {PInterfaces}ToolUtils.p
  91. Inside Macintosh reference: I-468
  92. Trap number: A906
  93. Moves or purges memory.
  94. NewString allocates the specified string as a relocatable object in the heap and
  95. returns a handle to it.
  96.  
  97. Note:  NewString returns a handle to a string whose size is based on its
  98.        actual length (not necessarily 255); if you're going to use Pascal
  99.        string functions that could change the length of the string, you may
  100.        want to call SetString or the Memory Manager procedure SetHandleSize
  101.        first to set the string to the maximum size.
  102. ----------
  103.  
  104. Read that note carefully -- it's there to help stop you making a stupid
  105. mistake.
  106.  
  107. NewString is taking what's in your string variable (errorString) and
  108. copying it into a *new* string in a handle.  What's in errorString?
  109. You don't know -- you've never put anything in it so it could be
  110. totally random.  The chances are though, that it's pretty short -- the
  111. chances are excellent that it's zero to ten characters long.  That means
  112. that errorStringH points to something that it probably much smaller
  113. than is needed to hold a full Str255.
  114.  
  115.  
  116. >         HLock(errorStringH);
  117. >         GetIndString(**errorStringH, IO_ERROR_STRINGS, 
  118. >             -1 * errornumber - ZEROTH_IO_ERROR );
  119.  
  120. BANG!  You probably just corrupted the heap by writing past the end of
  121. the space pointed to by errorStringH.
  122.  
  123. Either errorString or &errorString would have been fine here (either because
  124. C automatically takes the address of an array in a parameter context
  125. -- bletch).  Either *errorStringH (which I'd prefer) or your
  126. **errorStringH would have been fine if you'd made sure there was
  127. enough space for the result -- something like "errorStringH =
  128. NewHandle(256)" would have been fine instead of the NewString.
  129.  
  130.  
  131. >         if ( errorString == NIL_POINTER) {
  132.  
  133. Huh??
  134.  
  135. Three things wrong here:
  136.  
  137. 1) errorString has nothing to do with errorStringH at this point.
  138. errorStringH points at a *copy* of errorString, not at the original.
  139. The GetIndString will change the copy but not the original.
  140.  
  141. 2) GetIndString returns an empty string on error, not a null pointer.
  142. RTFM above -- and there's no way it *could* return a null pointer,
  143. since you're supplying the storage for it to alter, not the other way around.
  144.  
  145. You should be testing **errorStringH == 0 or (*errorStringH)[0] == 0 or
  146. errorString[0] == 0 (if you weren't using the unnecesary errorStringH).
  147.  
  148.  
  149. 3) It's not possible for "errorString == NIL_POINTER" to ever be true,
  150. since errorString (really &errorString because of C's automatic conversion) is
  151. a local variable on the stack and thus can never have an address of zero.
  152.  
  153.  
  154. The rest of the code looks OK.
  155.  
  156. You've got two options:
  157.  
  158. 1) junk errorString, change the NewString to NewHandle and
  159. "errorString == NIL_POINTER" to "**errorStringH == 0".
  160.  
  161. or
  162.  
  163. 2) junk errorStringH and use errorString or &errorString (the & will
  164. always be reundant in C) and "errorString[0] == 0".
  165.  
  166. -- Bruce
  167.    (who didn't mean to be as abusive as he probably sounded)
  168.  
  169. -- 
  170. Bruce.Hoult@bbs.actrix.gen.nz   Twisted pair: +64 4 477 2116
  171. BIX: brucehoult                 Last Resort:  PO Box 4145 Wellington, NZ
  172. "Cray's producing a 200 MIPS personal computer with 64MB RAM and a 1 GB
  173. hard disk that fits in your pocket!"   "Great!  Is it PC compatable?"
  174.