Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2 3  Все   Вниз
  Печать  
Автор Тема: sqlplus  (Прочитано 68243 раз)
0 Пользователей и 1 Гость смотрят эту тему.
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« : 29-07-2008 11:11 » 

Всем привет. Пишу замену, для себя, интерпретатора SQL, sqlplus. Основная проблема конечно же заключается в рисовании красивой таблицы, как у MySQL. У sqlplus даже с выставлением параметров типа "set page, set line" ничего хорошего не добиться. Так вот я и решил для себя сделать читаемый вывод данных по запросу. Пока мне нужно отрисовывать таблицу которая помещается на экран, т.е. пока не нужно заботиться о переводе строк или каком нибудь скролинге. Скролинг таблицы будет дальше с помощью библиотеки ncurses, но и там есть проблемы, скролинг на сколько я понял там только вертикальный, а мне еще понадобится скролинг горизонтальный, поэтому эту библиотеку скорее всего придется дорабатывать. И так сейчас проблема в следующем.

Есть мой класс:

Код:
class c_sqlplus
{
    public:
            void f_execute();
            void f_draw(SACommand*);

            int len_f[1024];
            int len_v[1024];
            const char* buff_value[1024];
            const char* buff_field[1024];

            c_sqlplus();
            ~c_sqlplus();
};

SACommand -- это класс библиотеки SQLAPI с помощью которой я общаюсь с БД Oracle.

Внутри моей функции f_execute(); я захожу в другую мою функцию f_draw(SACommand*); передавая указатель на заранее созданный экземпляр класса, как видно из названия функции я рисую (таблицу):

Код:
void c_sqlplus::f_draw(SACommand* cmd_in)
{
    cmd_in = new SACommand;
    using namespace std;

    for(int k=0; k<cmd_in->FieldCount(); k++) //
    {
        len_f[k] = strlen(buff_field[k]);
        len_v[k] = strlen(buff_value[k]);
        cout << "+";

        if(len_f[k] > len_v[k])
        {
            for(int i=0; i<len_f[k]; i++)
                cout << "-";
        }

        if(len_f[k] < len_v[k])
        {
            for(int i=0; i<len_v[k]; i++)
                cout << "-";
        }

                //cout << "+";
    }
}

рисовалка корявая пока что Улыбаюсь

так вот если этот блок рисования поместить в основную функцию программы то все проходит хорошо, а если этот блок поместить в отдельную функцию, как сейчас то программа валится на Segmentation fault. Я не могу понять почему. Этот блок нужно держать в отдельной функции потому что повторяется несколько раз в основной функции.

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

Код:
con.Connect(instance, user, passwd, SA_Oracle_Client);

установка соединения, дебагер завершает свою работу и говорит что программа выполнена. Подскажите что я не так делаю?
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 29-07-2008 11:15 » 

код маленький, отследить строку, где вываливаемся, очень просто - закомментируй половину , запусти. Если не отвалилось, значит ошибка в коменте (и наоборот) , так найди строку с ошибкой Улыбаюсь
Записан

McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #2 : 29-07-2008 11:18 » 

Алексей1153++, я комментировал всю функцию, f_draw() но вход в нее оставлял, и все равно падает. Я подозреваю что я как-то не так передаю указатель в эту функцию Улыбаюсь хотя вроде все просто. В общем башка кипит уже.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 29-07-2008 11:19 » 

а ещё, где гарантия, что массивы в этих строках
Код:
        len_f[k] = strlen(buff_field[k]);
        len_v[k] = strlen(buff_value[k]);
заканчиваются нулями ?
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 29-07-2008 11:20 » 

а покажи пример вызова
Записан

McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #5 : 29-07-2008 11:20 » 

Алексей1153++, это пока что тестовые массивы и я так думаю что на данное поведение оно не влияет Улыбаюсь
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 29-07-2008 11:20 » 

McZim, посмотрел бы в сторону oracle forms, oracle reports

т.е. по сутьи дела, то что ты хочешь уже давно реализовано самим ораклом
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 29-07-2008 11:20 » 

Я тоже думаю, что segmentation fault образуется где-то при выходе за границы массива.

Кстати, почему так:
Код:
            const char* buff_value[1024];
            const char* buff_field[1024];
? Ага
« Последнее редактирование: 29-07-2008 11:22 от Вад » Записан
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #8 : 29-07-2008 11:21 » 

Код:
void c_sqlplus::f_execute()
{
...
...
c_sqlplus::f_draw(cmd);
...
}
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #9 : 29-07-2008 11:22 » 

Sla, я делаю это только по одной причине, по той что я очень много работаю удаленно с Oracle базамы по ssh и мне нужен удобный консольный инструмент.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #10 : 29-07-2008 11:24 » 

Алексей1153++, вот более детальней по поводу вызова функции:

Код:
void c_sqlplus::f_execute()
{
...
...
SACommand* cmd = new SACommand; // create command object
...
try
    {
        con.Connect(instance, user, passwd, SA_Oracle_Client);
        cmd->setConnection(&con);
...
...
while(cmd->FetchNext())
        {
            for(int k = 0; k < cmd->FieldCount(); k++)
            {
                buff_field[k] = cmd->Field(k+1).Name();
                buff_value[k] = cmd->Field(k+1).asString();
            }
//-----------------------------------------------------
            c_sqlplus::f_draw(cmd);
//-----------------------------------------------------
...
...
   }
...
...
}
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #11 : 29-07-2008 11:26 » 

так дело в том что существует консольная версия oracle formsa
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #12 : 29-07-2008 11:27 » 

и летит именно на строке  c_sqlplus::f_draw(cmd); ? А если её закоментить ?
Записан

McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #13 : 29-07-2008 11:32 » new

Sla, а нет ли случаем где нить скриншотов этого дела? гугл ничего не дал.
Алексей1153++, странно, закоментил ошибка осталась Улыбаюсь но 100% если я вставлю блок из функции рисования в основную функцию, а функцию рисования убью то будет все рисоваться и не будет падать Улыбаюсь проверено.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #14 : 29-07-2008 11:36 » 

это может быть наведённая ошибка. Разбирайся с кодом до вызова )
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #15 : 29-07-2008 11:38 » 

например, должно быть, думается
Код:
for(int k = 0; k+1 <  cmd->FieldCount() && k<1024; k++)
Записан

Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #16 : 29-07-2008 11:38 » 

вот может быть здесь что-нибудь найдешь http://www.oracle.com/technology/products/forms/techlisting10g.html#client

я от оракла, к сожалению, далеко отошел, но знаю что есть контора, которая работает с формсом в консоли и именно через ссш
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #17 : 29-07-2008 11:43 » 

Алексей1153++, я только что убил функцию рисования, из нее вынул код и вставил в те места где раньше был вызов функции рисования и все заработало, ничего не упало.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #18 : 29-07-2008 11:45 » 

Алексей1153++, массивы которые тебя смущают, могу заменить на вектора Улыбаюсь
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #19 : 29-07-2008 11:54 » 

Макс, при чём тут нафик вектора Улыбаюсь Ты пробовал с k+1 <  ? Это точно косяк
Записан

McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #20 : 29-07-2008 11:56 » 

Алексей1153++, пробовал та же петрушка, хотя с таким циклом (как у меня) нормально работает если без функции рисования.
« Последнее редактирование: 29-07-2008 12:00 от McZim » Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #21 : 29-07-2008 12:04 » 

Уже и так пробовал, думал может что то намудрил с указателями?

Код:
SACommand cmd; // create command object

c_sqlplus::f_draw(&cmd);

Код:
void c_sqlplus::f_draw(SACommand*)
{
}
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #22 : 29-07-2008 12:05 » 

ну не знаю, на компилятор если ещё погрешить, то попробуй добавить в прототип рисовалки "cmd" , а не просто тип-указатель, а ещё при вызове функции убрать "класс::"
Записан

McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #23 : 29-07-2008 12:06 » 

Алексей1153++,

Код:
sudo aptitude show gcc
[sudo] password for mczim:
Пакет: gcc
Состояние: установлен
Автоматически установлен: да
Версия: 4:4.2.3-1ubuntu6
Приоритет: необязательный
Раздел: devel
Сопровождающий: Ubuntu Core developers <ubuntu-devel-discuss@lists.ubuntu.com>
Размер в распакованном виде: 65,5k
Зависимости: cpp (>= 4:4.2.3-1ubuntu6), gcc-4.2 (>= 4.2.3-1)
Рекомендует: libc6-dev | libc-dev
Предлагает: autoconf, automake1.9, bison, flex, gcc-doc, gcc-multilib, gdb, libtool, make, manpages-dev
Конфликтует: gcc-doc (< 1:2.95.3)
Предоставляет: c-compiler
Описание: компилятор GNU C
 Это компилятор GNU C, весьма портабельный оптимизирующий компилятор языка С.

 Этот пакет зависимостей предоставляет компилятор по умолчанию GNU C.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #24 : 29-07-2008 12:24 » 

ну собственно все понятно!!! Улыбаюсь Воспользовавшись программой valgrind, увидел слудующее

Код:
==13941==
==13941== Use of uninitialised value of size 4
==13941==    at 0x80499C4: c_sqlplus::f_execute() (main.cpp:72)
==13941==    by 0x8049EB5: main (main.cpp:7)
==13941==
==13941== Process terminating with default action of signal 11 (SIGSEGV)
==13941==  Bad permissions for mapped region at address 0x4010DC0
==13941==    at 0x80499C4: c_sqlplus::f_execute() (main.cpp:72)
==13941==    by 0x8049EB5: main (main.cpp:7)
==13941==
==13941== ERROR SUMMARY: 1790 errors from 192 contexts (suppressed: 80 from 1)
==13941== malloc/free: in use at exit: 1,281,487 bytes in 540 blocks.
==13941== malloc/free: 1,386 allocs, 846 frees, 1,395,502 bytes allocated.
==13941== For counts of detected errors, rerun with: -v
==13941== searching for pointers to 540 not-freed blocks.
==13941== checked 2,082,012 bytes.
==13941==
==13941== LEAK SUMMARY:
==13941==    definitely lost: 8,976 bytes in 20 blocks.
==13941==      possibly lost: 10,843 bytes in 23 blocks.
==13941==    still reachable: 1,261,668 bytes in 497 blocks.
==13941==         suppressed: 0 bytes in 0 blocks.
==13941== Rerun with --leak-check=full to see details of leaked memory.
Segmentation fault

смотрим вот сюда ==13941==    at 0x80499C4: c_sqlplus::f_execute() (main.cpp:72), смотрим в код и видим что строка 72 это:

Код:
buff_field[k] = cmd.Field(k+1).Name();

Цитата
valgrind - a suite of tools for debugging and profiling programs

мда...
« Последнее редактирование: 29-07-2008 12:26 от McZim » Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #25 : 29-07-2008 12:49 » 

хм, заменил строку buff_field[k] = cmd.Field(k+1).Name(); на field.push_back((const char*)cmd.Field(k+1).Name());, соответственно описав вектор std::vector<std::string> field;

видим теперь такое:

Код:
SQL> select * from bm_staff;
==15828==
==15828== Use of uninitialised value of size 4
==15828==    at 0x804A8D9: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (stl_vector.h:599)
==15828==    by 0x8049A7A: c_sqlplus::f_execute() (main.cpp:72)
==15828==    by 0x804A0A3: main (main.cpp:7)
==15828==
==15828== Use of uninitialised value of size 4
==15828==    at 0x804A8DF: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (stl_vector.h:599)
==15828==    by 0x8049A7A: c_sqlplus::f_execute() (main.cpp:72)
==15828==    by 0x804A0A3: main (main.cpp:7)
==15828==
==15828== Use of uninitialised value of size 4
==15828==    at 0x804A8E9: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (stl_vector.h:601)
==15828==    by 0x8049A7A: c_sqlplus::f_execute() (main.cpp:72)
==15828==    by 0x804A0A3: main (main.cpp:7)
==15828==
==15828== Invalid write of size 4
==15828==    at 0x41AB680: std::string::_Alloc_hider::_Alloc_hider(char*, std::allocator<char> const&) (basic_string.h:242)
==15828==    by 0x41A7E48: std::string::string(std::string const&) (basic_string.tcc:188)
==15828==    by 0x804A32C: __gnu_cxx::new_allocator<std::string>::construct(std::string*, std::string const&) (new_allocator.h:107)
==15828==    by 0x804A903: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (stl_vector.h:601)
==15828==    by 0x8049A7A: c_sqlplus::f_execute() (main.cpp:72)
==15828==    by 0x804A0A3: main (main.cpp:7)
==15828==  Address 0x8b1572ec is not stack'd, malloc'd or (recently) free'd
==15828==
==15828== Process terminating with default action of signal 11 (SIGSEGV)
==15828==  Access not within mapped region at address 0x8B1572EC
==15828==    at 0x41AB680: std::string::_Alloc_hider::_Alloc_hider(char*, std::allocator<char> const&) (basic_string.h:242)
==15828==    by 0x41A7E48: std::string::string(std::string const&) (basic_string.tcc:188)
==15828==    by 0x804A32C: __gnu_cxx::new_allocator<std::string>::construct(std::string*, std::string const&) (new_allocator.h:107)
==15828==    by 0x804A903: std::vector<std::string, std::allocator<std::string> >::push_back(std::string const&) (stl_vector.h:601)
==15828==    by 0x8049A7A: c_sqlplus::f_execute() (main.cpp:72)
==15828==    by 0x804A0A3: main (main.cpp:7)
==15828==
==15828== ERROR SUMMARY: 1802 errors from 195 contexts (suppressed: 80 from 1)
==15828== malloc/free: in use at exit: 1,281,508 bytes in 541 blocks.
==15828== malloc/free: 1,389 allocs, 848 frees, 1,395,551 bytes allocated.
==15828== For counts of detected errors, rerun with: -v
==15828== searching for pointers to 541 not-freed blocks.
==15828== checked 2,082,108 bytes.
==15828==
==15828== LEAK SUMMARY:
==15828==    definitely lost: 8,976 bytes in 20 blocks.
==15828==      possibly lost: 10,864 bytes in 24 blocks.
==15828==    still reachable: 1,261,668 bytes in 497 blocks.
==15828==         suppressed: 0 bytes in 0 blocks.
==15828== Rerun with --leak-check=full to see details of leaked memory.
Segmentation fault

Address 0x8b1572ec is not stack'd, malloc'd or (recently) free'd, что же за напасть такая вротмненоги Улыбаюсь
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #26 : 29-07-2008 12:52 » 

кстате какая конструкция более приемлема с точки зрения передачи указателя в функцию?

Код:
SACommand cmd;
f_draw(&cmd);

или

Код:
SACommand* cmd = new SACommand;
f_draw(cmd);

или на вкус и цвет пошел на ..уй
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #27 : 29-07-2008 13:27 » 

McZim, первое предпочтительнее, если можно обойтись без второго. Иногда можно только второй вариант применить. А сама передача указателя - в обоих случаях один хрен )
Записан

McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #28 : 29-07-2008 13:28 » 

Алексей1153++, Улыбаюсь ясно.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #29 : 29-07-2008 13:30 » 

Макс, ну в баню вектор, ни при чём он, не в работе с масивами ошибка , поробуй так
(и не забывай про k+1 !!!!!!!! Это же важно, иначе твой cmd->Field(k+1) - это косяк)
Код:
while(cmd->FetchNext())
        {
            for(int k = 0; k+1 < cmd->FieldCount(); k++)
            {
                buff_field[k] = "111"/*cmd->Field(k+1).Name()*/;
                buff_value[k] = "222"/*cmd->Field(k+1).asString()*/;
            }
Записан

Страниц: [1] 2 3  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines