• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

Looping array frequently goes out of bounds

Guest
Apr 16, 2010 Apr 16, 2010

Copy link to clipboard

Copied

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,'Name') and  structkeyexists(arguments.variablesToInclude,'value')>
                                             <VAR name="#ucase(arguments.variablesToInclude['Name'])#" value="#ucase(arguments.variablesToInclude['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,'Name') and  structkeyexists(arguments.variablesToInclude,'value')>
          <VAR name="#ucase(arguments.variablesToInclude['Name'])#" value="#ucase(arguments.variablesToInclude['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.

TOPICS
Advanced techniques

Views

3.0K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Explorer , Apr 16, 2010 Apr 16, 2010

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.

Votes

Translate

Translate
LEGEND ,
Apr 16, 2010 Apr 16, 2010

Copy link to clipboard

Copied

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?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Apr 16, 2010 Apr 16, 2010

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 16, 2010 Apr 16, 2010

Copy link to clipboard

Copied

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?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Apr 16, 2010 Apr 16, 2010

Copy link to clipboard

Copied

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\utilities.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:28)     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\utilities.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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Apr 16, 2010 Apr 16, 2010

Copy link to clipboard

Copied

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\utilities.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:28)     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\utilities.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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Apr 16, 2010 Apr 16, 2010

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Apr 16, 2010 Apr 16, 2010

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Apr 16, 2010 Apr 16, 2010

Copy link to clipboard

Copied

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

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Apr 17, 2010 Apr 17, 2010

Copy link to clipboard

Copied

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?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Apr 17, 2010 Apr 17, 2010

Copy link to clipboard

Copied

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?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Valorous Hero ,
Apr 17, 2010 Apr 17, 2010

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guest
Apr 17, 2010 Apr 17, 2010

Copy link to clipboard

Copied

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Advocate ,
Apr 18, 2010 Apr 18, 2010

Copy link to clipboard

Copied

LATEST

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.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources
Documentation