Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - raised exception class EAccesViolation при вызове LSQ_InsertFrontElement

Ответить
Настройки темы
C/C++ - raised exception class EAccesViolation при вызове LSQ_InsertFrontElement

Новый участник


Сообщения: 6
Благодарности: 0

Профиль | Отправить PM | Цитировать


что-то в функции LSQ_InsertFrontElement неправильно сделано


вот фаилы:
.c http://yadi.sk/d/SMXZ5cLR3JVRr
.h http://yadi.sk/d/Go_5SIwB3IKuM
или ниже код:
//___________________________________
Код: Выделить весь код
#ifndef LINEAR_SEQUENCE_H_INCLUDED
#define LINEAR_SEQUENCE_H_INCLUDED
#include <stdlib.h>


typedef int LSQ_BaseTypeT;     /* Тип хранимых в контейнере значений */

typedef void* LSQ_HandleT;     /* Дескриптор контейнера */

#define LSQ_HandleInvalid NULL /* Неинициализированное значение дескриптора контейнера */

typedef void* LSQ_IteratorT;   /* Дескриптор итератора */

typedef int LSQ_IntegerIndexT; /* Тип целочисленного индекса контейнера */

/* Функция, создающая пустой контейнер. Возвращает назначенный ему дескриптор */
extern LSQ_HandleT LSQ_CreateSequence(void);

/* Функция, добавляющая элемент в начало контейнера */
extern void LSQ_InsertFrontElement(LSQ_HandleT handle, LSQ_BaseTypeT element);

#endif
//______________________________________________________________________________
//______________________________________________________________________________

typedef struct LSQ_HandleT     //контейнер
{
    //LSQ_BaseTypeT *ptr;      //Тип хранимых в контейнере значений
    LSQ_IntegerIndexT size;    //Кол-во элементов //Тип целочисленного индекса контейнера
    struct LSQ_Element *HeadElement;//указатель на первый элемент контейнера (вместо void - LSQ_Element)
    struct LSQ_Element *TailElement;//указатель на последний элемент контейнера (вместо void - LSQ_Element)
};

typedef struct LSQ_Iterator
{
    struct LSQ_Element *CurrentElement;//указатель на текущий эл-т
    struct LSQ_HandleT *Container;   //указатель на контейнер
};

typedef struct LSQ_Element
{
    struct LSQ_Element *PrewElement; //указатели на пред. и след. элемент контейнера
    struct LSQ_Element *NextElement;
    LSQ_BaseTypeT Data;
    LSQ_IntegerIndexT Index;         //номер элемента
};
//______________________________________________________________________________

LSQ_HandleT LSQ_CreateSequence()     //создать контейнер
{  // Потом все функции надо в отдельный фаил переместить   [C++ Warning] linear_sequence.h(100): W8058 Cannot create pre-compiled header: code in header
    struct LSQ_HandleT* handle = (struct LSQ_HandleT*)malloc(sizeof(struct LSQ_HandleT));
    (*handle).size = 0;
    (*handle).HeadElement = NULL;
    (*handle).TailElement = NULL;
	return (LSQ_HandleT)handle;
}

void LSQ_InsertFrontElement(LSQ_HandleT handle, LSQ_BaseTypeT element) /* Функция, добавляющая элемент в начало контейнера */
{
    struct LSQ_Element* ElementHandle = (struct LSQ_Element*)malloc(sizeof(struct LSQ_Element));
    struct LSQ_HandleT* con = handle;  //делаем типизированный указатель
    (*ElementHandle).Data = element;
    (*con).size++;                    //raised exception class EAccesViolation
    //(*handle).size++;
	//(*(LSQ_Container *)handle).size++;
	//((LSQ_Container *)handle)->size++;
    if (((*con).size) == 1)
    {
        (*con).TailElement = ElementHandle;
        (*ElementHandle).NextElement = NULL;
    }else{
        (*ElementHandle).NextElement = (*con).HeadElement;
        (*con).HeadElement->PrewElement = ElementHandle;
    }
    (*ElementHandle).PrewElement = NULL;
    (*con).HeadElement = ElementHandle;
}

Отправлено: 07:52, 17-03-2013

 

Аватара для lxa85

Необычный


Contributor


Сообщения: 4463
Благодарности: 994

Профиль | Сайт | Отправить PM | Цитировать


pkkirill, правильно, а что вы хотели?
Вы делаете указатель на некоторую область памяти, а затем делаете "указатель + 1" это несанкционированная попытка доступа к памяти. Такие фокусы запрещены ЕМНИП с 80386 процессоров, когда появился защищенный режим.
Сейчас попробую объяснить на пальцах.

Вот мы получили указатель Handle. Он ссылается на некоторую ячейку памяти. Дальше, вместо того, чтобы вызвать отдельную процедуру выделения памяти, ты говоришь size+1. Что происходит в этом случае? (Во первых я не совсем понял, что за size, но предположу, что размер контейнера; Во вторых плюс один "чего"? Байт, Слово, Длинное слово?)
Указывая на некоторую ячейку А, мы хотим получить прямой доступ к ячейке А+1. Но! Никто не гарантирует, что ячейка А+1 свободна. В ней могут содержать данные других программ! Это потенциально ведет к нарушению целостной работы системы.

Посмотрите Переполнение буфера и Переполнение буфера для чайника(последняя для новичков, но не чайников)

-------
- Я не разрешаю тебе быть плохой! Потому что плохие люди совершают плохие поступки. А это нехорошо!
(Из наставлений 5 летней девочки своей младшей сестре)

Это сообщение посчитали полезным следующие участники:

Отправлено: 09:07, 17-03-2013 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.


Новый участник


Сообщения: 6
Благодарности: 0

Профиль | Отправить PM | Цитировать


в поле size хранится кол-во элементов в контейнере
я хочу увеличить значение поля size в структуре, адрес которой хранится в переменной con
то есть по идее (*con).size и есть это значение?
а (*con).size++; должно увеличивать это значение на 1

Я правильно понимаю?
*con мы получаем саму структуру по ее адресу
(*con).size - получаем поле size данной структуры

Отправлено: 09:57, 18-03-2013 | #3


Аватара для lxa85

Необычный


Contributor


Сообщения: 4463
Благодарности: 994

Профиль | Сайт | Отправить PM | Цитировать


Цитата pkkirill:
Я правильно понимаю? »
Понимаешь то правильно, только делаешь не правильно.
Смотри еще наглядней.
Есть карта политическая карта мира (оперативная память). На карте есть государства Европа, Россия, Китай и т.д. всё как полагается. Эта территория отведена под страны (под программы). Ты делаешь переменную-ссылку, допустим на Францию (con). А затем хочешь легким росчерком пера расширить ее границы. Мол, ребят, соседние государства, простите, но мне тут ваши луга и леса нужны, поэтому отныне вы (size+1, хопа!) мои! Ни тебе согласования границ (межевание, кадастровая регистрация, международные отношения), ни военной экспансии, ничего! Просто взял карандашом и нарисовал границы как тебе нравятся.
Непойдет. Неа
Хочешь расширять границы -- вызывай процедуры согласования земель. Оператор new или ему подобный.

-------
- Я не разрешаю тебе быть плохой! Потому что плохие люди совершают плохие поступки. А это нехорошо!
(Из наставлений 5 летней девочки своей младшей сестре)

Это сообщение посчитали полезным следующие участники:

Отправлено: 13:41, 18-03-2013 | #4


Новый участник


Сообщения: 6
Благодарности: 0

Профиль | Отправить PM | Цитировать


size это просто число в структуре типа LSQ_HandleT*, которую мы уже создали в функции LSQ_CreateSequence(), память для этой структуры мы выделили (malloc) и даже присвоили значение полю size=0;
Код: Выделить весь код
LSQ_HandleT LSQ_CreateSequence()     //создать контейнер
{  // Потом все функции надо в отдельный фаил переместить   [C++ Warning] linear_sequence.h(100): W8058 Cannot create pre-compiled header: code in header
    struct LSQ_HandleT* handle = (struct LSQ_HandleT*)malloc(sizeof(struct LSQ_HandleT));
    (*handle).size = 0;
    (*handle).HeadElement = NULL;
    (*handle).TailElement = NULL;
	return (LSQ_HandleT)handle;
}
теперь в функции LSQ_InsertFrontElement память выделяется только для структуры типа LSQ_Element*,
а указатель на стр-ру типа LSQ_HandleT* (память для которой уже выделялась раннее) идет в качестве параметра данной функции,
который затем типизируется таким способом struct LSQ_HandleT* con = handle;

вот кстати C-фаил:
Код: Выделить весь код
#include <stdio.h>
#include "linear_sequence.h"

int main()
{
  LSQ_BaseTypeT e = 9;
  LSQ_HandleT sec = LSQ_CreateSequence;
  printf("LSQ_CreateSequence %d\n",sec);
  LSQ_InsertFrontElement(sec,e);

  getchar();  return 0;
}

Отправлено: 17:12, 18-03-2013 | #5


Аватара для lxa85

Необычный


Contributor


Сообщения: 4463
Благодарности: 994

Профиль | Сайт | Отправить PM | Цитировать


Можно получить полный код проекта? (Если не полный, то воспроизводимый с инструкциями)
Какая среда разработки используется?
Цитата pkkirill:
EAccesViolation »
Здесь есть достаточно интересный анализ возникновения данной ошибки. Правда на Delphi, но сути я думаю не изменит.

-------
- Я не разрешаю тебе быть плохой! Потому что плохие люди совершают плохие поступки. А это нехорошо!
(Из наставлений 5 летней девочки своей младшей сестре)

Это сообщение посчитали полезным следующие участники:

Отправлено: 17:57, 18-03-2013 | #6


Новый участник


Сообщения: 6
Благодарности: 0

Профиль | Отправить PM | Цитировать


вот все что из папки с проектом
среда C++ Builder 6

Отправлено: 08:29, 19-03-2013 | #7


Новый участник


Сообщения: 6
Благодарности: 0

Профиль | Отправить PM | Цитировать


все дело было в неправильном вызове функции CreateSequence:
Код: Выделить весь код
#include <stdio.h>
#include "linear_sequence.h"

int main()
{
  LSQ_BaseTypeT e = 9;
  LSQ_HandleT sec = LSQ_CreateSequence;
  printf("LSQ_CreateSequence %d\n",sec);
  LSQ_InsertFrontElement(sec,e);

  getchar();  return 0;
}
исправил на CreateSequence();

Отправлено: 19:05, 21-03-2013 | #8



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - raised exception class EAccesViolation при вызове LSQ_InsertFrontElement

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Сбой при удаленном вызове процедуры Andrushind Microsoft Windows NT/2000/2003 4 15-09-2013 18:38
MSFT SQL Server - Ошибка при вызове Job Tonny_Bennet Программирование и базы данных 3 23-09-2011 11:44
Flash - Карта памяти Class 10 и Class 10 100x Baiker Накопители (SSD, HDD, USB Flash) 0 07-09-2011 01:13
Сбой при удаленном вызове процедуры. helgart Microsoft Windows NT/2000/2003 0 30-03-2011 13:55
Разное - Ошибка при вызове посты с клавиатуры interminable Microsoft Windows Vista 6 11-09-2007 14:24




 
Переход