13 Replies Latest reply on Apr 18, 2010 1:37 AM by Jochem van Dieten

    Looping array frequently goes out of bounds

    kenji776 Level 1

      Hello all,

      I have a process which pulls information from a database, converts the data into an array, in which every element contains a structure with two keys (name and value). That information is then processed and returned to another system. The problem is, often times when looping over the array that contains the structures, the loop will go out of bounds and attempt to access array elements that do not exist. Further more, sometimes either the "name" or "value" key will be blank. I currently am unaware of any pattern to this behavior.

       

      <!--- Get all the data for the given PID (an ID number associated to a contact) --->
      <cfquery name="Login" datasource="WebServer" maxrows="1">
           Select *
           From SFContactSync
           Where PID = <cfqueryparam cfsqltype="cf_sql_integer" value="#form.PID#">
      </cfquery>
      
      <!--- Assign All the information from the login query into variables we can return --->
      <cfloop list="#Login.columnList#" index="columnName">
           <cfset counter = counter + 1>
           <cfset VariablesObject[counter] = structnew()>
           <cfset VariablesObject[counter]["Name"] = columnName>
           <cfset VariablesObject[counter]["Value"] = #Login[columnName][1]#>
      </cfloop>
      
      <!--- Create one more entry that contains the full name of the person --->
      <cfset counter = counter + 1>
      <cfset VariablesObject[counter] = structnew()>
      <cfset VariablesObject[counter]["Name"] = "FullName">
      <cfset VariablesObject[counter]["Value"] = "#Login.Firstname# #Login.Lastname#">
      
      <!--- Set the next page to go to --->
      <cfset nextPage = "/15">
      
      <cfset ReturnObject = server.IVRUtilities.printMessage(nextPage,VariablesObject)>     
           
      
      <!--- Function for creating return AngelXML --->     
      <cffunction name="printMessage" access="remote" hint="Print a message for the Angel IVR System">
           <cfargument name="address" default="none" type="string">
           <!--- This is an array of structures, with keys "name" and "value" --->
           <!--- EX variables[1].Name = Gender --->
           <!--- EX variables[1].Value = Male --->
           <cfargument name="variablesToInclude" default="" type="any" required="no">
           <cfargument name="promptText" default="." type="string" required="no">
           <cfoutput>
                <cfsavecontent variable="ReturnMessage">
                     <ANGELXML>
                          <MESSAGE>
                               <PLAY>
                                    <PROMPT type="text">
                                         <cfoutput>#arguments.promptText#</cfoutput>
                                    </PROMPT>
                               </PLAY>
                               <GOTO destination="#listlast(address)#" />
                          </MESSAGE>
                          <cfif IsArray(arguments.variablesToInclude)>
                               <VARIABLES>
                                    <cftry>
                                         <cfloop from="1" to="#arraylen(arguments.variablesToInclude)#" index="i">
                                              <cfif structkeyexists(arguments.variablesToInclude[i],'Name') and  structkeyexists(arguments.variablesToInclude[i],'value')>
                                                   <VAR name="#ucase(arguments.variablesToInclude[i]['Name'])#" value="#ucase(arguments.variablesToInclude[i]['Value'])#" />
                                              </cfif>
                                         </cfloop>
                                         <cfcatch type="any">
                                              <cfset ErrorData = structnew()>
                                              <cfset ErrorData.Error = cfcatch>
                                              <cfset ErrorData.Arguments = arguments>
                                              <cfset ErrorData.form = form>
                                              <cfset SendError = server.utilities.SendErrorReport(ErrorData)>
                                         </cfcatch>
                                    </cftry>     
                               </VARIABLES>
                          </cfif>     
                          </ANGELXML>
                </cfsavecontent>
           </cfoutput>
           
           <cfreturn ReturnMessage>
      </cffunction>
      

       

      For example, I have an error sitting in my inbox now that says

       

       

      The element at position 25 cannot be found.

       

      But viewing the dump of the included elements shows only 24 elements. For some reason the loop here

      <cfloop from="1" to="#arraylen(arguments.variablesToInclude)#" index="i">
           <cfif structkeyexists(arguments.variablesToInclude[i],'Name') and  structkeyexists(arguments.variablesToInclude[i],'value')>
                <VAR name="#ucase(arguments.variablesToInclude[i]['Name'])#" value="#ucase(arguments.variablesToInclude[i]['Value'])#" />
           </cfif>
      </cfloop>
      

      does seem to stop at the right point. The cfif statment would error, becuase it tries to evaluate an array element that does not exist. Whats up with that?

       

      I was thinking of adding more checking to see if the array element exsists, but I am hesitant to add any more "checking" code than I really need beucase this is a somewhat high performance critical app. Any thoughts or comments are welcome.

        • 1. Re: Looping array frequently goes out of bounds
          Dan Bracuk Level 5

          Look's like a case of overengineering.  What do you think you can accomplish with an array of structures that you can't accomplish with the initial query?

          • 2. Re: Looping array frequently goes out of bounds
            kenji776 Level 1

            Mostly the fact that I wanted that function to be reuseable, there are several occasions where I need to create the AngelXML data, and I don't know ahead of time what kind of data I am going to be passing, if any. The array of structures gives me the flexibility to pass it any kind of data. Sometimes i need to populate it from a query, other times I pass it just a hard coded ID.

            • 3. Re: Looping array frequently goes out of bounds
              yui8979 Level 1

              I can't see anything wrong with your code. What do you get when you dump out

              the array length of that variable, at each iteration, from inside the

              function's loop?

              • 4. Re: Looping array frequently goes out of bounds
                kenji776 Level 1

                I'll try putting in some more debugging. When I dump out all the arguments, I clearly see there are 24 array elements, but it attempts to loop to 25. You're thinking maybe somehow the data is being affected in the loop?

                 

                Here is a sample dump

                 

                 

                An error has occurred in a Cold Fusion page template. All the information available is included below. Please note that not all included data may be relevent, but is included for completness sake.

                Error Info

                struct

                ARGUMENTS

                struct

                ADDRESS

                /7

                PROMPTTEXT

                .

                VARIABLESTOINCLUDE

                array

                1

                struct

                Name

                ACCOUNTID

                Value

                x

                2

                struct

                Name

                ACTIVATED

                Value

                [empty         string]

                3

                struct

                Name

                AGE

                Value

                41

                4

                struct

                Name

                BIRTHDATE

                Value

                1969-03-11

                5

                struct

                Name

                CONTACTDUPECHECKFIELD

                Value

                x

                6

                struct

                Name

                CONTACTFINGERPRINT

                Value

                [empty         string]

                7

                struct

                Name

                CONTACTID

                Value

                x

                8

                struct

                Name

                EMAIL

                Value

                x

                9

                struct

                Name

                EMAILSOPENED

                Value

                1

                10

                struct

                Name

                EMAILSSENT

                Value

                6

                11

                struct

                Name

                FIRSTNAME

                Value

                x

                12

                struct

                Name

                FULLNAME

                Value

                x

                13

                struct

                Name

                GENDER

                Value

                Male

                14

                struct

                Name

                IVRCALLSANSWERED

                Value

                0

                15

                struct

                Name

                IVRCALLSMADE

                Value

                1

                16

                struct

                Name

                LASTMODIFIED

                Value

                2010-02-22         21:42:28.607

                17

                struct

                Name

                LASTNAME

                Value

                x

                18

                struct

                Name

                LASTPUSH

                Value

                2010-04-02         03:02:33.65

                19

                struct

                Name

                PHONE

                Value

                x

                20

                struct

                Name

                PID

                Value

                x

                21

                struct

                Name

                PIN

                Value

                x

                22

                struct

                Name

                PORTALLOGINS

                Value

                1

                23

                struct

                Name

                SYNCEDTOSF

                Value

                0

                24

                struct

                Name

                FullName

                Value

                x

                ERROR

                struct

                Detail

                [empty     string]

                ErrNumber

                0

                Message

                The     element at position 25 cannot be found.

                StackTrace

                coldfusion.runtime.CfJspPage$ArrayBoundException:     The element at position 25 cannot be found. at     coldfusion.runtime.CfJspPage.ArrayGetAt(CfJspPage.java:869) at     coldfusion.runtime.CfJspPage._arrayGetAt(CfJspPage.java:930) at     coldfusion.runtime.CfJspPage._arrayGetAt(CfJspPage.java:925) at     cfutilities2ecfc868057140$funcPRINTMESSAGE.runFunction(C:\Website\Components\IVR\utilitie s.cfc:130)     at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:418) at     coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:324)     at     coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:59)     at coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:277) at     coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:192) at     coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:448) at     coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:308) at     coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2272) at     cfAuthenticate2ecfm747801116.runPage(C:\Website\Portal\IVR\Authenticate.cfm:85)     at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:196) at     coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:370) at     coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:65) at     coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:279) at     coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48)     at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40) at     coldfusion.filter.PathFilter.invoke(PathFilter.java:86) at     coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:70) at     coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:2 8)     at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38) at     coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46) at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38)     at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22) at     coldfusion.filter.RequestThrottleFilter.invoke(RequestThrottleFilter.java:126)     at coldfusion.CfmServlet.service(CfmServlet.java:175) at     coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89) at     jrun.servlet.FilterChain.doFilter(FilterChain.java:86) at     coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42 )     at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)     at jrun.servlet.FilterChain.doFilter(FilterChain.java:94) at     jrun.servlet.FilterChain.service(FilterChain.java:101) at     jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:106) at     jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42) at     jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:286)     at     jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543)     at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:203)     at     jrunx.scheduler.ThreadPool$DownstreamMetrics.invokeRunnable(ThreadPool.java:320)     at     jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428)     at jrunx.scheduler.ThreadPool$UpstreamMetrics.invokeRunnable(ThreadPool.java:266)     at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)

                TagContext

                array

                1

                struct

                COLUMN

                0

                ID

                ??

                LINE

                130

                RAW_TRACE

                at         cfutilities2ecfc868057140$funcPRINTMESSAGE.runFunction(C:\Website\Components\IVR\utilitie s.cfc:130)

                TEMPLATE

                C:\Website\Components\IVR\utilities.cfc

                TYPE

                CFML

                2

                struct

                COLUMN

                0

                ID

                CF_TEMPLATEPROXY

                LINE

                85

                RAW_TRACE

                at         cfAuthenticate2ecfm747801116.runPage(C:\Website\Portal\IVR\Authenticate.cfm:85)

                TEMPLATE

                C:\Website\Portal\IVR\Authenticate.cfm

                TYPE

                CFML

                Type

                Expression

                aDimension

                -1

                aIndex

                25

                FORM

                struct

                AUTHTOKEN

                [empty     string]

                CALLDIRECTION

                Outbound

                CALLGUID

                x

                DEBUG

                false

                DISCONNECTPAGE

                /140

                FAILPAGE

                /155

                FIELDNAMES

                CALLGUID,DISCONNECTPAGE,SUBSCRIBERID,PID,LOGINPAGE,NEXTPAGE,FAILPAGE,PIN,CALLDIRECTION

                LOGINPAGE

                /4

                NAVCODE

                [empty     string]

                NEXTPAGE

                /7

                PID

                x

                PIN

                [empty     string]

                SUBSCRIBERID

                x

                FromEmail

                x

                Subject

                Error   in template

                x

                 

                Message was edited by Jochem van Dieten to remove privae information.

                • 5. Re: Looping array frequently goes out of bounds
                  kenji776 Level 1

                  Wow, it gets weirder. I just got an error report, it tried to access element 17, even though there was only one argument. Am I maybe dealing with variable scope issue here?

                  An error has occurred in a Cold Fusion page template. All the information available is included below. Please note that not all included data may be relevent, but is included for completness sake.

                  Error Info

                  struct

                  ARGUMENTS

                  struct

                  ADDRESS

                  /140

                  PROMPTTEXT

                  .

                  VARIABLESTOINCLUDE

                  array

                  1

                  struct

                  NAME

                  ID

                  VALUE

                  081FAFF5-C299-2427-53D7A6720B424A41

                  ERROR

                  struct

                  Detail

                  [empty     string]

                  ErrNumber

                  0

                  Message

                  The     element at position 17 cannot be found.

                  StackTrace

                  coldfusion.runtime.CfJspPage$ArrayBoundException:     The element at position 17 cannot be found. at     coldfusion.runtime.CfJspPage.ArrayGetAt(CfJspPage.java:869) at     coldfusion.runtime.CfJspPage._arrayGetAt(CfJspPage.java:930) at     coldfusion.runtime.CfJspPage._arrayGetAt(CfJspPage.java:925) at     cfutilities2ecfc868057140$funcPRINTMESSAGE.runFunction(C:\Website\Components\IVR\utilitie s.cfc:130)     at coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:418) at     coldfusion.runtime.UDFMethod$ArgumentCollectionFilter.invoke(UDFMethod.java:324)     at     coldfusion.filter.FunctionAccessFilter.invoke(FunctionAccessFilter.java:59)     at coldfusion.runtime.UDFMethod.runFilterChain(UDFMethod.java:277) at     coldfusion.runtime.UDFMethod.invoke(UDFMethod.java:192) at     coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:448) at     coldfusion.runtime.TemplateProxy.invoke(TemplateProxy.java:308) at     coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:2272) at     cfLogcallNew2ecfm465243765.runPage(C:\Website\Portal\IVR\LogcallNew.cfm:46)     at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:196) at     coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:370) at     coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:65) at     coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:279) at     coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:48)     at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40) at coldfusion.filter.PathFilter.invoke(PathFilter.java:86)     at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:70) at     coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:2 8)     at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38) at     coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:46) at     coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38) at     coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22) at     coldfusion.CfmServlet.service(CfmServlet.java:175) at     coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:89) at     jrun.servlet.FilterChain.doFilter(FilterChain.java:86) at     coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:42 )     at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:46)     at jrun.servlet.FilterChain.doFilter(FilterChain.java:94) at     jrun.servlet.FilterChain.service(FilterChain.java:101) at     jrun.servlet.ServletInvoker.invoke(ServletInvoker.java:106) at jrun.servlet.JRunInvokerChain.invokeNext(JRunInvokerChain.java:42)     at     jrun.servlet.JRunRequestDispatcher.invoke(JRunRequestDispatcher.java:286)     at     jrun.servlet.ServletEngineService.dispatch(ServletEngineService.java:543)     at jrun.servlet.jrpp.JRunProxyService.invokeRunnable(JRunProxyService.java:203)     at     jrunx.scheduler.ThreadPool$DownstreamMetrics.invokeRunnable(ThreadPool.java:320)     at     jrunx.scheduler.ThreadPool$ThreadThrottle.invokeRunnable(ThreadPool.java:428)     at jrunx.scheduler.ThreadPool$UpstreamMetrics.invokeRunnable(ThreadPool.java:266)     at jrunx.scheduler.WorkerThread.run(WorkerThread.java:66)

                  TagContext

                  array

                  1

                  struct

                  COLUMN

                  0

                  ID

                  ??

                  LINE

                  130

                  RAW_TRACE

                  at         cfutilities2ecfc868057140$funcPRINTMESSAGE.runFunction(C:\Website\Components\IVR\utilitie s.cfc:130)

                  TEMPLATE

                  C:\Website\Components\IVR\utilities.cfc

                  TYPE

                  CFML

                  2

                  struct

                  COLUMN

                  0

                  ID

                  CF_TEMPLATEPROXY

                  LINE

                  46

                  RAW_TRACE

                  at         cfLogcallNew2ecfm465243765.runPage(C:\Website\Portal\IVR\LogcallNew.cfm:46)

                  TEMPLATE

                  C:\Website\Portal\IVR\LogcallNew.cfm

                  TYPE

                  CFML

                  Type

                  Expression

                  aDimension

                  -1

                  aIndex

                  17

                  FORM

                  struct

                  CONTACTATTEMPT

                  1

                  DATESTAMP

                  {ts     '2010-04-16 14:36:54'}

                  ID

                  081FAFF5-C299-2427-53D7A6720B424A41

                  Subject

                  Error   in template

                   

                  • 6. Re: Looping array frequently goes out of bounds
                    yui8979 Level 1

                    You might be on to something there ... your function is Server scoped? you

                    need to var scope the variables in your cfffunction for them to be trully

                    local

                     

                    <cfset var x = "">

                    <cfset var ReturnMessage = "">

                    etc.

                    • 7. Re: Looping array frequently goes out of bounds
                      kenji776 Level 1

                      The only variables I use are the ones passed into the arguments, and the loop counter defined as i. if I create i as a local variable and set it to 0 perhaps that will clear the issues up.

                      • 8. Re: Looping array frequently goes out of bounds
                        Adam Cameron. Level 5

                        kenji776 wrote:

                         

                        The only variables I use are the ones passed into the arguments, and the loop counter defined as i. if I create i as a local variable and set it to 0 perhaps that will clear the issues up.

                         

                        You should always VAR all variables used in functions, unless you specifically want them to be shared across method calls.

                         

                        It looks to me like you have your CFC instantiated in some shared scope, and - given you are not VARing any variables - all requests calling those methods are sharing those variables.  This will yield "unexpected" results.

                         

                        --

                        Adam

                        • 9. Re: Looping array frequently goes out of bounds
                          -==cfSearching==- Level 4

                          Wow, it gets weirder. I just got an error report

                           

                          I suspect Adam is correct about the missing var scoping. 

                           

                          BTW: The account and pin numbers you posted ... are they for anything important? 

                          • 10. Re: Looping array frequently goes out of bounds
                            kenji776 Level 1

                            Seems you guys were probably right about the var scoping being the issue. For some reason I had it in my head that variables created within loops where local to that loop or something. Doesn't make much sense in retrospect. Creating the variable beforehand, and setting it to 0 seems to has resolved the issue.

                             

                            That extra info in the dump isn't anything terribly important (you can only get into some small website that doesn't have any really useful info) but I'll remove it anyway. Thanks for the heads up.

                             

                            Edit: Damn, for some reason I cannot modify my above posts. Hey mods, if you see this, can you kill those post above witht he dump info in there please?

                            • 11. Re: Looping array frequently goes out of bounds
                              -==cfSearching==- Level 4
                              Creating the variable beforehand, and setting it to 0 seems to has resolved the issue.

                               

                               

                              I assume you mean you "var" scoped the variable? Be sure to do the same for all of the function-local variables (ie ones you do not want shared).

                               

                              Edit: Damn, for some reason I cannot modify my above posts. Hey mods, if you see this, can you kill those post above witht he dump info in there please?

                              I do not think this forum has that kind of moderator.

                               

                              That extra info in the dump isn't anything terribly important (you can only get into some small website that doesn't have any really useful info) but I'll remove it anyway. Thanks for the heads up.

                               

                              Always  scrub stuff before posting. Most forums are routinely archived by search engines  and other sites. So once you post something, the original is out there (on one site or another) ... most likely  permanently.

                              • 12. Re: Looping array frequently goes out of bounds
                                kenji776 Level 1

                                Yeah I set it as a var. I normally do, just I didn't really think I had to for a for that variable, figured the loop would

                                re-init it at 0, but that was a dumb assumption. Thats weird I can't edit posts, and there are no mods. Sure I made a mistake, but the fact

                                that there is no way to correct it is fairly stupid.

                                • 13. Re: Looping array frequently goes out of bounds
                                  Jochem van Dieten Level 4

                                  As son as somebody has replied to a message the message can not be changed anymore, except by a moderator. If you need something fixed in a post, click the "Report abuse" link and explain what needs to be done.