Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Нарушение прав доступа при записи, Висящий указатель нашел, но не знаю как  
:(
    Опции темы
Shmell
  Дата 14.2.2012, 21:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 14.2.2012

Репутация: нет
Всего: нет



Здравствуйте!
Имеется программа поиска коллизий в хэш-функции


Код



#include <stdio.h>
#include <stdlib.h>

#define n 30 //размер таблицы
 
unsigned int ELFHash(char* str, unsigned int len) // хэш-функция ELF
{
   unsigned int hash = 0;
   unsigned int x    = 0;
   unsigned int i    = 0;

   for(i = 0; i < len; str++, i++)
   {
      hash = (hash << 4) + (*str);
      if((x = hash & 0xF0000000L) != 0)
      {
         hash ^= (x >> 24);
      }
      hash &= ~x;
   }
                              

        return hash%21; //коллизия при ключах 22-30
}
 
void main ()
{
        int table[n][2];
        int i, j=0, ch=1; // параметры цикла,  вводная переменная
        char key; // ключ
        //очищение хэш-таблицы
        for(i=0; i<n; i++)
        {
                table[i][0] = 0; //место для ключа
                table[i][1] = 0; //место для адреса в таблице
        }
        
        system("cls");
        while(ch != 0)
        {
                printf("\t\t\tMenu: Please select\n\t1 - Watch hash-table.\n\t2 - new key.\n\t3 Search. 0 Exit\n"); // имитация меню
                scanf("%d", &ch); // считывание символа
                if(ch > 1)
                {
                        printf("Enter the key: ");
                        scanf ("%d", &key);
                }
                switch(ch){
                        case 1: printf("[N]\tKey\tAdress", table[i][0], table[i][1]);  //вывод на экран хэш-таблицы
                                for(i=0; i<n; i++)
                                        printf("[%d]\t%d\t%d", i+1, table[i][0], table[i][1]);
                                break;
                        case 2: for(i=0; i<n*10; i++)                             //n*10 потому что после 250 проверок функции бессмысленно проверять дальше
                                        if(table[ELFHash(&key, n)+i*3+i*i*7][0] != 0) //проверка на свободное место в таблице
                                        {
                                                table[ELFHash(&key, n)+i*3+i*i*7][0] = key;
                                                table[ELFHash(&key, n)+i*3+i*i*7][1] = ++j;
                                                printf("\tKey was write after %d attempt", i);
                                        }
                                if(i==n*10) printf("Table is overload! Needs rehashing!!!");
                                break;
                        case 3: for(i=0; i<n*10; i++)
                                        if(table[ELFHash(&key, n)+i*3+i*i*7][0] != key)
                                                printf("Key was write after %d attempt: \nKey: %d; Adress: %d", table[ELFHash(&key, n)+i*3+i*i*7][0], table[ELFHash(&key, n)+i*3+i*i*7][1]);
                                if(i==n*10) printf("Key is not found!");
                                break;
                        default: printf("Error!");
                }
        }
}





Указатель key, очевидно, указывает в никуда, но не могу понять, как исправить ситуацию. Помогите, пожалуйста.

Отладка

Это сообщение отредактировал(а) Shmell - 14.2.2012, 21:55
PM MAIL   Вверх
borisbn
Дата 14.2.2012, 22:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(Shmell @  14.2.2012,  21:52 Найти цитируемый пост)
 char key; // ключ

Цитата(Shmell @  14.2.2012,  21:52 Найти цитируемый пост)
 scanf ("%d", &key);

scanf ожидает указатель на int, а ты даёшь ему указатель на char


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Shmell
Дата 14.2.2012, 22:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 66
Регистрация: 14.2.2012

Репутация: нет
Всего: нет



Diabolis Interium! Исправил!
Код

scanf ("%с", &key);

Но проблема осталась.
И еще есть замечания такого типа:
user posted image
PM MAIL   Вверх
feodorv
Дата 14.2.2012, 23:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Цитата(Shmell @  14.2.2012,  21:52 Найти цитируемый пост)
#define n 30

Цитата(Shmell @  14.2.2012,  21:52 Найти цитируемый пост)
int table[n][2]

Цитата(Shmell @  14.2.2012,  21:52 Найти цитируемый пост)
for(i=0; i<n*10; i++)
    if(table[ELFHash(&key, n)+i*3+i*i*7][0] != 0)

Это нормально, что индекс таблицы (ELFHash(&key, n)+i*3+i*i*7) может превысить её размер (n)? smile 


Цитата(Shmell @  14.2.2012,  22:30 Найти цитируемый пост)
И еще есть замечания такого типа

И? В варнингах предлагается отказаться от scanf в пользу scanf_s)))

Добавлено через 11 минут и 12 секунд
Цитата(Shmell @  14.2.2012,  21:52 Найти цитируемый пост)
        char key; // ключ

Цитата(Shmell @  14.2.2012,  21:52 Найти цитируемый пост)
if(ch > 1)
                {
                        printf("Enter the key: ");
                        scanf ("%d", &key);
                }


Строка задаётся как массив символов:
Код

char key[1024];


Соответственно, считать строку можно так:
Код

scanf( "%s", key);

(здесь не учитывается размер буфера key, может произойти переполнение, из-за чего и нужна scanf_s) либо через fgets( key, sizeof(key), stdin) / gets(key). В последних случаях в считываемую с консоли строку попадает символ '\n' (перевод строки).


Цитата(Shmell @  14.2.2012,  21:52 Найти цитируемый пост)
ELFHash(&key, n)

Почему здесь тупо берётся n (фиксированное, означающее к тому же размер таблицы), а не strlen(key) (то есть длина ключа в байтах)????


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0443 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.