简体   繁体   中英

Array index out of bounds error C#

i have this code that im getting error and, and cant understand why im getting the error. the code is as following: im using two arrays a string and a double(data values with their corresponding tinestamp). But for some reason im getting error that: index out of bounds error on this line:

     getSelectedItemsObj.arrayOfTimeStamp        = GetItemData(parameterName[counter], fromTime, toTime).arrayOfTimeStamp;

If i remove this line and only use arrayOfValue the code works fine, but i need both

.......... Thanks for the fast replies, here is how GetItemData is set up

 public CustomDataType GetItemData(string parameterName, string fromTime, string toTime)
    {

        getWeatherItemObj = new CustomDataType();
        // get the parameter ID
        prameterID = GetParameterInfo(parameterName).ParameterID; 
        //get the nr of items to size value arrays
        tableSize = GetTableSize(parameterName, fromTime, toTime, prameterID);
        getWeatherItemObj.arrayOfValue      = new double[tableSize];            
        getWeatherItemObj.arrayOfTimeStamp  = new string[tableSize];
        counter = 0;
        try
        {
            using (conn = new SqlConnection(connectionString))// create and open a connection object
            {
                // 1. create a command object identifying the stored procedure
                 cmd = new SqlCommand("GetItemData", conn);
                // 2.Let the command object know we will execute a stored procedure
                cmd.CommandType = CommandType.StoredProcedure;
                // 3. add the 3 parameters to command, so the can be passed to the stored procedure                  
                cmd.Parameters.Add("@ParameterName", SqlDbType.VarChar).Value    = parameterName;
                cmd.Parameters.Add("@FromTime", SqlDbType.VarChar).Value                = fromTime;
                cmd.Parameters.Add("@ToTime", SqlDbType.VarChar).Value                  = toTime;
                //open connection
                conn.Open();
                // execute the command
                reader = cmd.ExecuteReader();
                if (reader.HasRows)
                {
                    while (reader.Read())
                    {
                        getWeatherItemObj.arrayOfValue[counter]         = (double)reader["MeasurementValue"];
                        getWeatherItemObj.arrayOfTimeStamp[counter]     = reader["MeasurementDateTime"].ToString();                          
                        counter++;
                    }
                } 
                //close connection
                reader.Close();            
            }
        }
        catch (SqlException e)
        {
            Console.WriteLine("Connection failed");
            Console.WriteLine(e.Message);
            Thread.Sleep(5000);
        }           
        return getWeatherItemObj;
    }






 class CustomDataType
{
    public double[] arrayOfValue;
    public string[] arrayOfTimeStamp;

}

public CustomDataType GetSelectedtemsData(string[] parameterName, string fromTime, string toTime)
    {
        numberOfParameters = parameterName.Length;//Get the number of given parameters
        tableSize = 0;
        for (counter = 0; counter < numberOfParameters; counter++)
        {
            tableSize = tableSize + GetItemData(parameterName[counter], fromTime, toTime).arrayOfTimeStamp.Length;               
        }

        getSelectedItemsObj = new CustomDataType();

        getSelectedItemsObj.arrayOfValue        = new double[tableSize];
        getSelectedItemsObj.arrayOfTimeStamp    = new string[tableSize];
        for (counter = 0; counter < tableSize; counter++)
        { 
            getSelectedItemsObj.arrayOfValue            = GetItemData(parameterName[counter], fromTime, toTime).arrayOfValue;
            getSelectedItemsObj.arrayOfTimeStamp        = GetItemData(parameterName[counter], fromTime, toTime).arrayOfTimeStamp;

        }
        return getSelectedItemsObj;
    }

The problem is in how you're treating your counter. If you remove the timestamp stuff, the counter never really gets modified so it all appears to work, but if you have the timestamp stuff in there, then your for loop initializer looks like this:

for (counter = 0; counter < tableSize; counter++)

where tableSize is ultimately greater than parameterName[].Length . Since later you're calling parameterName[counter] , counter will be out of bounds. You need to make sure that you're never attempting to access something in parameterName[] by an index that is not legal within that array.

Edit:
Another possibility, if removing only that line removes the error, is that the return of

GetItemData(parameterName[counter], fromTime, toTime).arrayOfTimeStamp;

is larger than the specified array allocated in

getSelectedItemsObj.arrayOfTimeStamp    = new string[tableSize];

In order to make such a determination, you would need to post the code to that method as well.

The problem is right here:

for (counter = 0; counter < tableSize; counter++)
{ 
     getSelectedItemsObj.arrayOfValue            = GetItemData(parameterName[counter], fromTime, toTime).arrayOfValue;
     getSelectedItemsObj.arrayOfTimeStamp        = GetItemData(parameterName[counter], fromTime, toTime).arrayOfTimeStamp;    
}

Your counter size is being incremented based on tableSize , but its being used as if its based on the size of parameterName . Nothing in your code enforces this assumption, so as soon as tableSize is larger than parameterName , you will get the error you are seeing.

Please try the following:

public CustomDataType GetSelectedtemsData(string[] parameterName, string fromTime, string toTime)
{
    CustomDataType tempObj;     // *Rename this variable*
    List<double> valueList = new List<double>();
    List<string> timeStampList = new List<string>();

    for (counter = 0; counter < parameterName.Length; counter++)
    {
        tempObj = GetItemData(parameterName[counter], fromTime, toTime);
        valueList.AddRange(tempObj.arrayOfValue);
        timeStampList.AddRange(tempObj.arrayOfTimeStamp);
    }

    getSelectedItemsObj = new CustomDataType();
    getSelectedItemsObj.arrayOfValue = valueList.ToArray();
    getSelectedItemsObj.arrayOfTimeStamp = timeStampList.ToArray();

    return getSelectedItemsObj;
}

I was going to try it your way, but once I realized you were pulling each parameterName 3 times, and the second loop would need an inner loop (since you would need to iterate through each index in each GetItemData), and that my fix would have resulted in multiple copies of the same data anyways; I decided to rebuild the method using two List .

If this does not solve your issue then I will need the complete error message, the stack trace from the error message, and the code of the top most method on the error stack.

Note: There are a number of additional optimizations which may help you like:

  • You may also want to update GetItemData to also use List instead of arrays so you can skip the tableSize = GetTableSize(parameterName, fromTime, toTime, prameterID); line.
  • You may want to change CustomDataType so arrayOfValue and arrayOfTimeStamp are not arrays. Then, instead of passing a CustomDataType out you could pass a CustomDataType[] or even List<CustomDataType> .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM