System.NullReferenceException: Object reference not set to an instance of an object в моей реализации хеш-таблицы при попытке создания новых массивов!
Возникла проблема конкретно в строках кода обозначенных дефисами или, если еще конкретнее, в строке под крестиками. При обращении к полю 'values' под индексом 'i' почему-то возвращает null. Очень интересно: в какой момент в поле 'values' переопределяется массив так, что в нем все значения становятся равны null, если я даже явно ничего не переопределял.
Также вкратце объясню что происходит: я связал 7 значений с 7 ключами, и затем хеш-функция увидела, что коэффициент заполненности словаря равен 7/10 и начала расширять этот словарь т.е переопределять в полях values и keys массивы с удвоенной величиной и переписывать в них данные из прошлых экземпляров этих массивов. Но когда функция начала переписывать значения ключей в буферный массив для оных, она заметила что из первой имплементации словааря(которую я вообще никак не переопределял)возвращаются значения null т.е я будто перед этим явно переопределил массив строк и не указал в нем никаких значений.
class Dict
{
private int dict_size;
public int values_counter = 0;
private int total = 0;
private char[] litters = {'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};
private int[] operands = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26 };
private string[] keys;
private string[] values;
public Dict(int dict_size)
{
this.dict_size = dict_size;
this.keys = new string[this.dict_size];
this.values = new string[this.dict_size];
}
public void Hash(string value, string key)
{
for (int i = 0; i < value.Length; i++)
{
for (int j = 0; j < this.litters.Length; j++)
{
if (this.litters[j] == Char.ToUpper(value[i]))
{
this.total += this.operands[j];
break;
}
}
}
this.keys[this.total%10] = key;
this.values[this.values_counter] = value;
this.values_counter++;
this.total = 0;
if ( ((float) this.values_counter/this.dict_size) >= 0.7f ) //-Проверка коэфф.заполненности--
{ //-----------------------------------------------------
string[] bufferKeys = new string[this.dict_size];
string[] bufferValues = new string[this.dict_size];
this.dict_size *= 2; // удвоение величины массивов ключей и значений
for (int i = 0; i < this.values.Length; i++) // берем строку из поля values
{
for (int j = 0; j < this.values[i].Length; j++) //ххххххххххххххххххххххххххххх
{ //^^^затем обращаемся к каждому отдельному символу в строке^^^
for (int k = 0; k < this.litters.Length; k++)//----------------------------------
{
if (this.litters[k] == Char.ToUpper(this.values[i][j]))
{
this.total += this.operands[k];
break;
}
}
}
bufferKeys[this.total%10] = this.keys[this.total%10];
total = 0;
}
for (int i = 0; i < this.values.Length; i++)
{
bufferValues[i] = this.values[i];
}
this.keys = new string[this.dict_size];
this.values = new string[this.dict_size];
for (int i = 0; i < bufferValues.Length; i++)
{
for (int j = 0; j < bufferValues[i].Length; j++)
{
for (int k = 0; k < this.litters.Length; k++)
{
if (this.litters[k] == Char.ToUpper(bufferValues[i][j]))
{
this.total += this.operands[k];
break;
}
}
}
this.keys[this.total%10] = bufferKeys[this.total%10];
total = 0;
}
for (int i =0; i < bufferValues.Length; i++)
{
this.values[i] = bufferValues[i];
}
}
}
public string Get(string value)
{
for (int i = 0; i < value.Length; i++)
{
for (int j = 0; j < this.litters.Length; j++)
{
if (this.litters[j] == Char.ToUpper(value[i]))
{
this.total += this.operands[j];
break;
}
}
}
var key = this.keys[this.total%10];
this.total = 0;
return key;
}
public string[] Keys
{
get{return this.keys;}
}
public string[] Values
{
get{return this.values;}
}
}
class Program
{
static void Main(string[] args)
{
Dict dict = new Dict(10);
dict.Hash("lesha", "kuvaev"); // 1
dict.Hash("masha", "stepanovna"); // 2
dict.Hash("macyanya", "chervyakova"); // 3
dict.Hash("evsikakiya", "spiridonovna"); // 4
dict.Hash("agent", "cry"); // 5
dict.Hash("pasha", "kyznecov"); // 6
dict.Hash("Alex", "Mercer"); // 7
//dict.Hash("Misha", "repin"); // 8
/*Console.WriteLine(dict.Get("Alex"));*/
for (int i = 0; i < dict.Keys.Length; i++)
{
if (dict.Keys[i] == null)
{
Console.WriteLine("-null-");
}
Console.WriteLine(dict.Keys[i]);
}
for (int i =0; i < dict.Values.Length; i++)
{
if (dict.Values[i] == null)
{
Console.WriteLine("-null-");
}
Console.WriteLine(dict.Values[i]);
}
Console.WriteLine(dict.values_counter);
}
}
Ответы (1 шт):
Все работает корректно, ну в смысле поведение ожидаемое, вы добавляете 7 значений и при этом у вас в это условие не было заходов. На восьмое значение if срабатывает и вы попадаете в цикл. Значения с 0 по 6 позицию в массиве есть (см. картинку), а вот на 7 позиции и далее честные null.
Я бы этот цикл обернул в if c проверкой что this.values[i] != null