A.I.M. Jagged Alliance2

Добро пожаловать, Гость. Пожалуйста, выберите:
Вход || Регистрация.
29.03.2024 в 02:13:30

Главная Главная Помощь Помощь Поиск Поиск Участники Участники Вход Вход Регистрация Регистрация
A.I.M. « С++ Вопросы и ответы. »
   A.I.M.
   Генерал
   Ъ и Ь
(Модераторы: Zed, cha, Снайпер)
   С++ Вопросы и ответы.
« Предыдущая Тема | Следующая Тема »
  Тема:  С++ Вопросы и ответы.             Страниц: 1 2 3 4 5 6 7 Прочитано 48820 раз
Korchy
[Непреодолимая сила]
Прирожденный Джаец

Ах, было б только с кем поговорить ...


WWW Ё-мэйл

Пол:
Репутация: +663
Re: С++
« Ответ #100 от 11.10.2011 в 00:43:01 »

11.10.2011 в 00:39:15, Artem13 писал(a):
В Билдере есть два компонента

В Борландовском? Я же не знаю задачи. Для простой передачи пакетов данных, типа чата - вполне.
Только учти что флеш использует только неблокируемые сокеты. Тебе скорее всего нужно будет использовать их же.
Зарегистрирован

ban.gif
jarni
[Гарный хлопец]
Прирожденный Джаец

Мне нечего сказать.


Ё-мэйл

Пол:
Репутация: +306
Re: С++
« Ответ #101 от 11.10.2011 в 01:06:14 »

11.10.2011 в 00:43:01, Korchy писал(a):
скорее всего нужно будет использовать их же
Если это не нужно самой программе, то в этом нету необходимости. В смысле, одну сторону соединения можно обрабатывать синхронным способом, другую асинхронным совершенно спокойно.
Зарегистрирован

Don't worry, be happy.
Korchy
[Непреодолимая сила]
Прирожденный Джаец

Ах, было б только с кем поговорить ...


WWW Ё-мэйл

Пол:
Репутация: +663
Re: С++
« Ответ #102 от 11.10.2011 в 02:14:26 »

11.10.2011 в 01:06:14, jarni писал(a):
Если это не нужно самой программе, то в этом нету необходимости. В смысле, одну сторону соединения можно обрабатывать синхронным способом, другую асинхронным совершенно спокойно.

Вообще, да, ты прав.
Зарегистрирован

ban.gif
Artem13
[13-й воин]
Прирожденный Джаец

Ап, и черти у ног моих сели...


WWW Ё-мэйл

Пол:
Репутация: +441
Re: С++
« Ответ #103 от 11.10.2011 в 02:53:09 »

2jarni: 2Korchy:  Спасибо, буду изучать :)
Зарегистрирован

Artem13.gif
http://www.aap13.narod.ru
И пули, что найдет тебя,
Ты не услышишь,
А остальные мимо пролетят

Artem13
[13-й воин]
Прирожденный Джаец

Ап, и черти у ног моих сели...


WWW Ё-мэйл

Пол:
Репутация: +441
Re: С++
« Ответ #104 от 01.11.2011 в 23:04:14 »

Продолжаем тему :)
Собсно, как то я с флэшкой взаимодействую. Теперь другой задача - как мне этот сторонний экзешник запустить/закрыть? Запустить я могу через ShellExecute, но тогда как останавливать. С другой стороны, вроде CreateProcess позволяет запустить внешний ехе и получить его хэндл дабы потом с ним манипулировать; однако вопрос - что будет с этим хэндлом, если внешний ехе закроется собственными средствами без моего вмешательства? Я об этом узнаю?
А може кто еще какие методы поскажет?
Зарегистрирован

Artem13.gif
http://www.aap13.narod.ru
И пули, что найдет тебя,
Ты не услышишь,
А остальные мимо пролетят

jarni
[Гарный хлопец]
Прирожденный Джаец

Мне нечего сказать.


Ё-мэйл

Пол:
Репутация: +306
Re: С++ Вопросы и ответы.
« Ответ #105 от 01.11.2011 в 23:33:14 »

2Artem13: CreateProcess это твое всё. :)
 
        STARTUPINFO      si = {0};
      PROCESS_INFORMATION pi = {0};
      si.cb = sizeof(si);
      if( CreateProcess(  
            "Имя экзешника",  
            "Аргументы",
            NULL,
            NULL,
                FALSE,
                0,
            "Переменные среды если надо",
            "Рабочая директория если надо поменять",
            &si,
            &pi <-- вот это тебе как раз и нужно) )
      {
            //m_hProcess = pi.hProcess;
            //m_pid                   = pi.dwProcessId;
 
//Вот так надо следить за процессом. Именно так ты узнаешь если процесс умер. Wait вывалится как раз в момент смерти. Хендл потом обязательно закрыть иначе будет хендл-лик у процесса (у винды ограничение на 16 млн хендлов но и это число мне однажды удалось достичь из-за утечки).
if( WAIT_OBJECT_0 == ::WaitForSingleObject(pi.hProcess, INFINITE) )
      {
                //Процесс больше не жилец
                //Eсли надо узнать с каким кодом процесс умер то делается это так
            DWORD dwExitCode;
            if( GetExitCodeProcess(m_hProcess, &dwExitCode) )
            {
                    //dwExitCode это та цифра с которой процесс вышел из main().
            }
      }
      }
« Изменён в : 01.11.2011 в 23:35:49 пользователем: jarni » Зарегистрирован

Don't worry, be happy.
Artem13
[13-й воин]
Прирожденный Джаец

Ап, и черти у ног моих сели...


WWW Ё-мэйл

Пол:
Репутация: +441
Re: С++ Вопросы и ответы.
« Ответ #106 от 02.11.2011 в 00:40:33 »

2jarni: сенькс. Мне за ним следить особо не надо, но я должен его убить при собственном закрытии, а закрытие уже убитого процесса в винде, емнип, приведёт к крашу.
Зарегистрирован

Artem13.gif
http://www.aap13.narod.ru
И пули, что найдет тебя,
Ты не услышишь,
А остальные мимо пролетят

jarni
[Гарный хлопец]
Прирожденный Джаец

Мне нечего сказать.


Ё-мэйл

Пол:
Репутация: +306
Re: С++ Вопросы и ответы.
« Ответ #107 от 02.11.2011 в 00:46:35 »

2Artem13: TerminateProcess не крешится, просто возвратит FALSE.
Зарегистрирован

Don't worry, be happy.
jarni
[Гарный хлопец]
Прирожденный Джаец

Мне нечего сказать.


Ё-мэйл

Пол:
Репутация: +306
Re: С++ Вопросы и ответы.
« Ответ #108 от 02.11.2011 в 00:53:25 »

А GetLastError в даннов случае возвращает ERROR_INVALID_HANDLE. Только что проверено.
Зарегистрирован

Don't worry, be happy.
Artem13
[13-й воин]
Прирожденный Джаец

Ап, и черти у ног моих сели...


WWW Ё-мэйл

Пол:
Репутация: +441
Re: С++ Вопросы и ответы.
« Ответ #109 от 02.11.2011 в 03:19:36 »

2jarni: Сенькс. Завтра попробую у себя.
Зарегистрирован

Artem13.gif
http://www.aap13.narod.ru
И пули, что найдет тебя,
Ты не услышишь,
А остальные мимо пролетят

Artem13
[13-й воин]
Прирожденный Джаец

Ап, и черти у ног моих сели...


WWW Ё-мэйл

Пол:
Репутация: +441
Re: С++ Вопросы и ответы.
« Ответ #110 от 03.11.2011 в 00:22:20 »

2jarni: Что я делаю не так? Срабатывает только со второго раза и процесс  не терминатится :(
Зарегистрирован

Artem13.gif
http://www.aap13.narod.ru
И пули, что найдет тебя,
Ты не услышишь,
А остальные мимо пролетят

jarni
[Гарный хлопец]
Прирожденный Джаец

Мне нечего сказать.


Ё-мэйл

Пол:
Репутация: +306
Re: С++ Вопросы и ответы.
« Ответ #111 от 03.11.2011 в 00:24:19 »

А на что ругается первый раз?
Зарегистрирован

Don't worry, be happy.
jarni
[Гарный хлопец]
Прирожденный Джаец

Мне нечего сказать.


Ё-мэйл

Пол:
Репутация: +306
Re: С++ Вопросы и ответы.
« Ответ #112 от 03.11.2011 в 00:52:37 »

Вот такой вот код
Code:

int main( int argc, char * argv[] )
{
  STARTUPINFO si = {0};
  PROCESS_INFORMATION pi = {0};
  si.cb = sizeof(si);
 
  if( !CreateProcess( "app.exe", NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, 0, &si,&pi) )
  {
    printf("Failed to create.\n" );
    return -1;
  }
 
  printf("Created.\n");
  if ( WaitForSingleObject( pi.hProcess, 10000 ) != WAIT_TIMEOUT )
  {
    printf("Dead :-(.\n");
    return -2;
  }
 
  printf("Alive.\n");
  UINT exit_code = 0xBAADF00D;
  if ( !TerminateProcess( pi.hProcess, exit_code ) )
  {
    printf("Failed to Terminate.\n" );
    return -3;
  }
 
  printf("Terminated.\n");
  if ( WaitForSingleObject( pi.hProcess, 10000 ) != WAIT_OBJECT_0 )
  {
    printf("Handle is not set.\n" );
    return -4;
  }
   
  printf("Dead :-).\n");
  DWORD dwExitCode = 0;
  if ( GetExitCodeProcess( pi.hProcess, &dwExitCode) )
  {
    printf("Terminated with ec: %x.\n", dwExitCode );
  }
  else
  {
    printf("Failed to get ec.\n" );
  }
 
  return 0;
}

 
у меня работает с вот таким результатом
Quote:

Created.
Alive.
Terminated.
Dead :-).
Terminated with ec: baadf00d.

 
app.exe это однострочная програмка
Code:

int main( int argc, char * argv[] )
{
  Sleep(3600000);
  return 0;
}

Зарегистрирован

Don't worry, be happy.
Artem13
[13-й воин]
Прирожденный Джаец

Ап, и черти у ног моих сели...


WWW Ё-мэйл

Пол:
Репутация: +441
Re: С++ Вопросы и ответы.
« Ответ #113 от 03.11.2011 в 03:40:58 »

03.11.2011 в 00:24:19, jarni писал(a):
А на что ругается первый раз?

ХЗ, я не смотрел еще, на скорую руку нарисовал, код ошибки не смотрел.
 
А в терминатор я код передавал 0. Я уже не помню какой там код нормального завершения должен быть.
 
Кстате, CloseHandle после терминатора не нужен?
Зарегистрирован

Artem13.gif
http://www.aap13.narod.ru
И пули, что найдет тебя,
Ты не услышишь,
А остальные мимо пролетят

jarni
[Гарный хлопец]
Прирожденный Джаец

Мне нечего сказать.


Ё-мэйл

Пол:
Репутация: +306
Re: С++ Вопросы и ответы.
« Ответ #114 от 03.11.2011 в 03:44:59 »

2Artem13:  03.11.2011 в 03:40:58, Artem13 писал(a):
Я уже не помню какой там код нормального завершения должен быть
А он у всех свой, но общепринятое - 0. Хотя встречал проги которые успешное завершение обозначают как 1, как аналог TRUE.
 
 03.11.2011 в 03:40:58, Artem13 писал(a):
Кстате, CloseHandle после терминатора не нужен?  
Надо. Забыл, опять забыл. (с) :)
Зарегистрирован

Don't worry, be happy.
Artem13
[13-й воин]
Прирожденный Джаец

Ап, и черти у ног моих сели...


WWW Ё-мэйл

Пол:
Репутация: +441
Re: С++ Вопросы и ответы.
« Ответ #115 от 22.02.2012 в 01:13:40 »

Я чего то опять туплю - давно не работал с контейнерами и не могу сообразить. Есть ли в С++/STL/ещё где-нибудь контейнер или алгоритм, позволяющий прямую и обратную выборку? Т.е. значение по ключу и ключ по значению. В принципе, размер небольшой и можно тупо два массива сварганизовать, но хочется изящно поизвращаться  :D
Зарегистрирован

Artem13.gif
http://www.aap13.narod.ru
И пули, что найдет тебя,
Ты не услышишь,
А остальные мимо пролетят

jarni
[Гарный хлопец]
Прирожденный Джаец

Мне нечего сказать.


Ё-мэйл

Пол:
Репутация: +306
Re: С++ Вопросы и ответы.
« Ответ #116 от 22.02.2012 в 01:25:36 »

2Artem13: НЯЗ в STL таких контейнеров нету. Но нужную тебе функциональность предоставляет любой STL контейнер с поиском по ключу + функция std::find. Только учти что у последней сложность O(n).
« Изменён в : 22.02.2012 в 01:26:18 пользователем: jarni » Зарегистрирован

Don't worry, be happy.
Korchy
[Непреодолимая сила]
Прирожденный Джаец

Ах, было б только с кем поговорить ...


WWW Ё-мэйл

Пол:
Репутация: +663
Re: С++ Вопросы и ответы.
« Ответ #117 от 22.02.2012 в 01:56:01 »

2Artem13:  
22.02.2012 в 01:13:40, Artem13 писал(a):
Есть ли в С++/STL/ещё где-нибудь контейнер или алгоритм, позволяющий прямую и обратную выборку?

std::map смотри. Поиск значения по ключу есть, поиск ключа по значению - циклом. На основе map'a сделан boost::multi_index, там вроде реализован и прямой и обратный поиск. Но если без буста, то через мап.
Зарегистрирован

ban.gif
Artem13
[13-й воин]
Прирожденный Джаец

Ап, и черти у ног моих сели...


WWW Ё-мэйл

Пол:
Репутация: +441
Re: С++ Вопросы и ответы.
« Ответ #118 от 22.02.2012 в 03:46:20 »

Спасибо, так и думал. Поизвращаюсь и так и эдак, наверное.
Зарегистрирован

Artem13.gif
http://www.aap13.narod.ru
И пули, что найдет тебя,
Ты не услышишь,
А остальные мимо пролетят

Ushwood
[ДжАдай]
Прирожденный Джаец

May the Force be with you


WWW Ё-мэйл

Пол:
Репутация: +562
Re: С++ Вопросы и ответы.
« Ответ #119 от 29.09.2012 в 01:00:50 »

Имею такой кусок кода:
 
Code:
const int lattice_size=50;
const int max_ncltd=30000;
int *lattice1;
 
...
 
lattice1=(int*)malloc(lattice_size*lattice_size*lattice_size*(max_ncltd+1)*sizeof(int));

 
При компиляции на последней приведенной строке выдается предупреждение: "warning C4307: '*' : integral constant overflow". Почему оно так и что сделать, чтоб его не было?
(интуитивно подозреваю, что проблема в размере этой переменной, которая состоит из 4е9 интов, но хотелось бы конкретнее...)
 
А, да: система Win7 32.
« Изменён в : 29.09.2012 в 01:02:16 пользователем: Ushwood » Зарегистрирован

Мои текущие переводы:
Червь арка 30, версия 24.03.24

Korchy
[Непреодолимая сила]
Прирожденный Джаец

Ах, было б только с кем поговорить ...


WWW Ё-мэйл

Пол:
Репутация: +663
Re: С++ Вопросы и ответы.
« Ответ #120 от 29.09.2012 в 03:50:26 »

2Ushwood:  
Потому что latticel объявлено как указатель на int. int имеет хранимый объем 4 байта. Выделяя память под массив в последней строчке ты выделяешь столько, что превосходишь максимальное число влезающее в 4 байта (-2^16 - 2^16).
Легко проверить, тоже самое предупреждение ты получишь при такой строке:
int a = INT_MAX+1;
 
Самое простое решение - переопредели *latticel на тип double (8 байт -2^32 - 2^32). Т.е. так:
 
double *latticel;
...
latticel = (double*)malloc( ... *sizeof(double));
Зарегистрирован

ban.gif
Ushwood
[ДжАдай]
Прирожденный Джаец

May the Force be with you


WWW Ё-мэйл

Пол:
Репутация: +562
Re: С++ Вопросы и ответы.
« Ответ #121 от 29.09.2012 в 06:50:27 »

2Korchy: Спасибо, попробую сделать так...
 
ммм, однако мне там удобнее работать с интами, чем с даблами... ладно, ченить придумаю.
Зарегистрирован

Мои текущие переводы:
Червь арка 30, версия 24.03.24

jarni
[Гарный хлопец]
Прирожденный Джаец

Мне нечего сказать.


Ё-мэйл

Пол:
Репутация: +306
Re: С++ Вопросы и ответы.
« Ответ #122 от 29.09.2012 в 07:00:11 »

2Ushwood: Использование другого типа тебе не поможет в данном конкретном случае. А то что посоветовал Никита так вообще. У тебя ведь не проблема в переменной для данных а в размере поля для этих данных. Если бы позволяла система то вполне хватило бы вместо const int использовать const unsigned long long, он 64битный беззнаковый, туда влезет очень много. Но система в твоём случае не позволяет. Ты хочешь создать ~15Гб, но на 32битной системе у тебя теоретических 4Гб, а фактических около 2Гб ну или 3Гб если использовать дополнительную опцию в настройках Винды.
« Изменён в : 29.09.2012 в 07:07:19 пользователем: jarni » Зарегистрирован

Don't worry, be happy.
Korchy
[Непреодолимая сила]
Прирожденный Джаец

Ах, было б только с кем поговорить ...


WWW Ё-мэйл

Пол:
Репутация: +663
Re: С++ Вопросы и ответы.
« Ответ #123 от 29.09.2012 в 09:15:51 »

2jarni:  
Проблема, насколько я понимаю, в том, что размер массива вылезает за адресацию int. Соот-но использование long или double без разницы, должно помочь. Я не задумывался, но разве в 32битной системе нельзя выделить память больше 2 гб? По идее система должна занять сколько сможет оперативки, а остальное начнет хешировать на диск.
Зарегистрирован

ban.gif
Korchy
[Непреодолимая сила]
Прирожденный Джаец

Ах, было б только с кем поговорить ...


WWW Ё-мэйл

Пол:
Репутация: +663
Re: С++ Вопросы и ответы.
« Ответ #124 от 29.09.2012 в 10:10:29 »

2Ushwood:  
Так работай с интами. Указатель должен быть большим, а не размер ячейки массива.
И да, Юра прав, используй long. Я забыл, что double это плавающая точка, он не хранит точных значений.
Так тогда получится:
 
long *lattice1;  
lattice1=(long*)malloc(lattice_size*lattice_size*lattice_size*(max_ncltd +1)*sizeof(int));
Зарегистрирован

ban.gif
Zed
[SIG edition ;)]
A.I.M.Director

Была такая игра Z


Ё-мэйл

Пол:
Репутация: +532
Re: С++ Вопросы и ответы.
« Ответ #125 от 29.09.2012 в 10:19:47 »

29.09.2012 в 09:15:51, Korchy писал(a):
не задумывался, но разве в 32битной системе нельзя выделить память больше 2 гб?
 
Можно, но не винде.
29.09.2012 в 09:15:51, Korchy писал(a):
По идее система должна занять сколько сможет оперативки, а остальное начнет хешировать на диск.  

А обращаться к памяти ты будешь через духов машины ? адресация то 32 битная.
Зарегистрирован

Кровавый ГБист, душитель свободы.
jarni
[Гарный хлопец]
Прирожденный Джаец

Мне нечего сказать.


Ё-мэйл

Пол:
Репутация: +306
Re: С++ Вопросы и ответы.
« Ответ #126 от 29.09.2012 в 10:22:29 »

2Korchy: Ты предложил заменить элементы int на double. Это точно не решает проблему потому что double элементов всё равно будешь создавать int штук. Поэтому я предложил оставить элементы int но количество штук заменить на 64битную величину.
 
Но это всё так сказать - фигня. Самая главная проблема состоит в адресном пространстве. Если ты создашь массив из 4е9 int'ов, то адрес первого будет, чисто теоретически, 0х00000000, адрес второго 0х00000004. С адресом 0хFFFFFFFC будет всего лишь 1073741823 элемент массива. И всё. То есть, из 4е9 элементов адресовать ты можешь только 1е9. Ну, можно конечно задать индекс 2000000000, но я не знаю что случиться первым, Segmentation Fault или перетечение адреса и соответственно адресация неправильного участка памяти. Уж лучше то первое.
 
АПДЕЙТ:
Никита, ты путаешь яблоки с грушами. long *lattice1;  это указатель на массив элементов типа long. Юре не нужен этот тип, ему нужны int'ы, к тому же на 32битной платформе у них одинаковый размер. Ему нужно увеличивать константы так как я писал. Тут вот в чём дело, компилятор имеет ряд вполне чётких правил преобразования типов.
lattice_size*lattice_size*lattice_size*(max_ncltd +1)*sizeof(int) это int*int*int*int*size_t.
50*50*50 - всё в порядке. Результат int
125000 * 30001 = 3750125000. Перетечение знакового типа, результат -544842296.
-544842296 * 4: -544842296 переводится в size_t потому что этот тип больше, 3750125000 * 4 = 2115598112. Перетечение, неверный результат. Поэтому нужен тип больше.
 
АПДЕЙТ2:
На первый взгляд может показаться что я написал тавтологию, 3750125000 --> -544842296 --> 3750125000. Но это тавтология только на 32битной платформе. Если оставить те же типы но скомпилировать код на 64 битной платформе то результат будет немного другим.
int на 64битах остаётся 32битным.
sizeof(int) возвращает значение типа size_t, которое на 64битной платформе имеет 64бита. Значит так. Первые 4 умножения происходят в рамках int с результатом -544842296. В хексе это 0хDF865DC8. Проблемка только в том что по правилам компилятора расширение типов происходит так: int --> int64 --> uint64, а это значит 0хDF865DC8 (int) --> 0xFFFFFFFFDF865DC8 (int64) --> 0xFFFFFFFFDF865DC8 (uint64). Последнее число в десятичной форме уже 18446744073164710000. Много, да. Потом ещё умножить на 4. Значение опять перетечёт, получится 0хFFFFFFFF7E197720, в дека 18446744071530183000. Не забываем что теперь это уже беззнаковое. Вот именно это число полезет в malloc (интерфейс void * malloc(size_t) ). Хех, столько памяти позволит аллоцировать разве что супер-пупер-мега кластер с дистрибуированной ОС, например IBM BlueGene.
« Изменён в : 29.09.2012 в 10:52:49 пользователем: jarni » Зарегистрирован

Don't worry, be happy.
jarni
[Гарный хлопец]
Прирожденный Джаец

Мне нечего сказать.


Ё-мэйл

Пол:
Репутация: +306
Re: С++ Вопросы и ответы.
« Ответ #127 от 29.09.2012 в 10:44:29 »

2Ushwood: Юр, если нету возможности портировать программу на 64битную платформу предлагаю разбить проблему на меньшие части и делать её по частям, "подсасывая" в нужный момент нужную часть. Например, если ты читаешь данные из файла, то создай массив размером в 1 млн. int'ов и залей в него первый миллион из файла. После обработки этого, залей второй на то же место и так победного конца. ;)
Зарегистрирован

Don't worry, be happy.
Ushwood
[ДжАдай]
Прирожденный Джаец

May the Force be with you


WWW Ё-мэйл

Пол:
Репутация: +562
Re: С++ Вопросы и ответы.
« Ответ #128 от 29.09.2012 в 11:06:11 »

2Korchy: 2jarni:  
Благодарю за советы. Осмыслив информацию, я понял, что мне нужно сделать ход конем. Осталось разобраться, что это за конь и как он должен ходить...
 
В общем, задача (точнее, подзадача), которую мне нужно решить, следующая.
 
У меня есть n точек в трехмерном пространстве, координаты которых мне задаются. Число n большое - порядка 1е6, но проблема не в них.
Пространство поделено кубической решеткой на m x m x m ячеек. Заранее известно, что в каждой ячейке может быть не больше n0 точек (n0=30000). Сколько именно точек окажется в какой ячейке - заранее неизвестно (я это узнаю, когда получаю координаты точек).
Задача: по номеру (i,j,k) кубической ячейки получить доступ ко всем точкам, которые в этой ячейке есть. Задачу надо решать много раз, поэтому вариант перебирать каждый раз все n точек сразу отметается.
 
Сперва у меня было m=25, и я решил задачу просто: сперва создал линейный массив (размером n) структур, где прописаны координаты каждой точки, потом создал массив int lattice[m][m][m][n0+1] и заполнил его: для каждого (i,j,k) я в ячейку [i][j][k][0] вписал количество точек в этой ячейке, а дальше - номера этих точек. Все было нормально, на машине с 4 гигами оперативки все работало.
 
Дальше понадобилось увеличить m как минимум до 50 (на самом деле - хорошо бы до 100), и начались проблемы. Компилить массив lattice[m][m][m][n0+1] Си просто отказался, когда я попытался обойти это дело с помощью указателей - выдал то, что я написал выше.
 
Теперь, собсно, свежие мысли. Реально ведь в этом массиве подавляющее большинство ячеек будут просто забиты нулями - ужасающе неэффективный расход памяти. Нельзя ли в каждой из этих 50х50х50 ячеек выделять объем не под максимальные 30000 точек, а индивидуально, под то количество точек, которые реально в эту ячейку попали? Чувствую, тут нужна какая-то химия врое массива указателей, но я в этой области плаваю...: idontknow :
« Изменён в : 29.09.2012 в 11:10:32 пользователем: Ushwood » Зарегистрирован

Мои текущие переводы:
Червь арка 30, версия 24.03.24

Korchy
[Непреодолимая сила]
Прирожденный Джаец

Ах, было б только с кем поговорить ...


WWW Ё-мэйл

Пол:
Репутация: +663
Re: С++ Вопросы и ответы.
« Ответ #129 от 29.09.2012 в 17:55:25 »

2jarni:  
Я предлагал менять не размер элементов а размер указателя на массив. Плохо наверное написал. И видимо да, с наскоку так просто проблему с адресацией не решить.
 
upd:
В любом случае не понимаю, почему нельзя сделать свой указатель, если системных не хватает. Что-то вроде
 
Определить массив
 
int BigArray[INT_MAX][INT_MAX];
 
И переопределить указатель:
 
int & operator [] (long id) const {
int FirstWord = id/INT_MAX;
int LastWord = id%INT_MAX;
return BigArray[FirstWord][LastWord];
}
« Изменён в : 29.09.2012 в 19:16:29 пользователем: Korchy » Зарегистрирован

ban.gif
Korchy
[Непреодолимая сила]
Прирожденный Джаец

Ах, было б только с кем поговорить ...


WWW Ё-мэйл

Пол:
Репутация: +663
Re: С++ Вопросы и ответы.
« Ответ #130 от 29.09.2012 в 18:07:11 »

29.09.2012 в 11:06:11, Ushwood писал(a):
В общем, задача (точнее, подзадача), которую мне нужно решить, следующая.  

Опять же решение с наскока: по точкам строить дерево. Для твоей задачи скорее всего Octree.
Зарегистрирован

ban.gif
Lion
[Lion. King Lion.]


Welcome to Metavira!




Пол:
Репутация: +362
Re: С++ Вопросы и ответы.
« Ответ #131 от 29.09.2012 в 18:30:20 »

2Ushwood: Можно мнение новичка?
 
Точки в процессе двигаются? Доступ нужен ко всем сразу или только к определённой части?
 
Если точки неподвижны и доступ нужен только к части из них, можно разделить все точки по полоскам m*m*5, например, и записывать на диск. Как в звёздном каталоге никто не держит информацию о миллиарде звёзд в одном файле.
 
 29.09.2012 в 11:06:11, Ushwood писал(a):
Нельзя ли в каждой из этих 50х50х50 ячеек выделять объем не под максимальные 30000 точек, а индивидуально, под то количество точек, которые реально в эту ячейку попали?
Думаю можно. При считывании точек на каждую ячейку пространства заводим счётчик cnt<n0 и указатель на первый элемент, лежащий в ячейке, который представляет структуру: элемент, указатель на следующий.
 
Считав точки, чтобы не возиться со списками в таком виде, переделываем структуру данных, делаем массив
m*m*m, каждый элемент которого является структурой данных вида: количество точек в этой ячейке (мы их уже сосчитали на предыдущем шаге), динамический массив из количества точек. (Или указатель на массив из количества точек плюс один, где в нулевой позиции хранится кол-во точек).
 
Если работать с этим потом долго, то подготовка может дать свои плюсы, тем более что второй этап должен неплохо параллелится.
 
При этом, чтоб меньше возиться с указателями, можно попробовать массив [m][m][m] заменить на линейный массив [m*m*m] - миллион указателей, должно влезть. Индексы обрабатывать вручную, работать может быстрее цепочек указателей.
« Изменён в : 29.09.2012 в 19:27:26 пользователем: Lion » Зарегистрирован

jarni
[Гарный хлопец]
Прирожденный Джаец

Мне нечего сказать.


Ё-мэйл

Пол:
Репутация: +306
Re: С++ Вопросы и ответы.
« Ответ #132 от 29.09.2012 в 23:17:12 »

2Korchy:  29.09.2012 в 17:55:25, Korchy писал(a):
Я предлагал менять не размер элементов а размер указателя на массив.
Диаметрально противоположно. Размер указателя на 32битной платформе всегда! равен 4байтам, хоть это char * хоть void * хоть uint64 *. Разница только в адресуемых элементах. Это же прописные истины указателей. Как твоя структура сможет получить доступ к последнему элементу BigArray? Суть не в том как ты посчитаешь координаты а в том как в конечном итоге это должен будет сделать компилятор. Читай ниже ответ Льву.
 
2Lion:  29.09.2012 в 18:30:20, Lion писал(a):
попробовать массив [m][m][m] заменить на линейный массив [m*m*m]
Лёва, учи матчасть. :) Компьютер абсолютно ничего не знает о двух-, трёх-, двадцати-мерных массивах. Все они у него линейные. Просто в случае одномерного массиву ты делаешь арифметику для доступа к ячейке (что-то вроде i*line_size + j), а в случае многомерного эту арифметику за тебя делает компилятор, то есть, a[i][j] он как раз пересчитывает на i*line_size + j.
 
2Ushwood: Моё предложение это хэш-таблица. Из координат i,j,k считаешь хэш. Под этим хэшем у тебя будет сохранён динамический массив. Время доступа в хэш-таблице в среднем равно 1 (всё зависит от количества коллизий). Динамический массив придётся написать самому или взять из интернета. Вся суть в том чтобы аллоцировать массив по кускам, скажем по 100 элементов, в идеальном случае PAGE_SIZE/sizeof(int) что обычно равно 1024 минус всякие вспомогательные вещи. Выравнивание на ширину страницы ускоряет управление памятью. При такой организации данных среднее время на сохранение одной точки будет равно 1, потому что вставка в хэш-таблицу как и поиск равно 1, и вставка в линейный массив нового элемента тоже равно 1.
 
Что-то я не нашёл сложность вставки и поиска в Octree, но у обычных бинарных деревьев это n*log(n) что тоже быстро но всё равно хуже 1.
 
Приметка: если каким то чудесным образом та наперёд знаешь сколько точек будет находится по каждой координате то автоматически отпадает потребность в динамическом массиве.
« Изменён в : 29.09.2012 в 23:20:37 пользователем: jarni » Зарегистрирован

Don't worry, be happy.
Korchy
[Непреодолимая сила]
Прирожденный Джаец

Ах, было б только с кем поговорить ...


WWW Ё-мэйл

Пол:
Репутация: +663
Re: С++ Вопросы и ответы.
« Ответ #133 от 30.09.2012 в 00:56:12 »

2jarni:  
Ок, наверное я не прав.
Зарегистрирован

ban.gif
Lion
[Lion. King Lion.]


Welcome to Metavira!




Пол:
Репутация: +362
Re: С++ Вопросы и ответы.
« Ответ #134 от 30.09.2012 в 01:15:13 »

2jarni: Если я правильно помню, в Си вообще нет массивов, есть синтаксическая конструкция их заменяющая. По сути является указателем на первый элемент.
Зарегистрирован

jarni
[Гарный хлопец]
Прирожденный Джаец

Мне нечего сказать.


Ё-мэйл

Пол:
Репутация: +306
Re: С++ Вопросы и ответы.
« Ответ #135 от 30.09.2012 в 03:09:24 »

2Korchy:  
Code:

int main( int argc, const char * argv[] )
{
  unsigned char dummy[] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0xAA, 0xAA, 0xAA, 0xAA, 0xBB, 0xBB, 0xBB, 0xBB };
  int * ptri = (int*)dummy;
  long * ptrl = (long*)dummy;
  long long * ptrll = (long long *)dummy;
  printf("int  : var size %u, ptr size %u ptr %p valueh 0x%X\n", sizeof(*ptri), sizeof(ptri), ptri, *ptri );
  printf("long : var size %u, ptr size %u ptr %p valueh 0x%X\n", sizeof(*ptrl), sizeof(ptrl), ptrl, *ptrl );
  printf("int64: var size %u, ptr size %u ptr %p valueh 0x%I64X\n", sizeof(*ptrll), sizeof(ptrll), ptrll, *ptrll );
 
  int (*ptrai)[2] = (int(*)[2])dummy;
  printf("0x%X 0x%X\n", ptrai[0][0], ptrai[0][1] );  
  printf("0x%X 0x%X\n", ptrai[1][0], ptrai[1][1] );  
  printf("ai   : var size %u, ptr size %u\n", sizeof(*ptrai), sizeof(ptrai) );  
 
  ptri = (int*)0xBAADF00D;
  int i = INT_MAX;
  int j = INT_MAX;
  int value11 = ptrai[i][j];
  printf("value: pointers: 0x%p == 0x%p, values: 0x%X == 0x%X\n", &ptrai[i][j], &ptri, ptrai[i][j], ptri );
  return 0;
}

Результат:
Code:

int  : var size 4, ptr size 4 ptr 0012FF50 valueh 0x67452301
long : var size 4, ptr size 4 ptr 0012FF50 valueh 0x67452301
int64: var size 8, ptr size 4 ptr 0012FF50 valueh 0xEFCDAB8967452301
0x67452301 0xEFCDAB89
0xAAAAAAAA 0xBBBBBBBB
ai   : var size 8, ptr size 4
value: pointers: 0x0012FF44 == 0x0012FF44, values: 0xBAADF00D == 0xBAADF00D

 
int i = INT_MAX;
00411501  mov    dword ptr [ebp-54h],7FFFFFFFh  
  int j = INT_MAX;
00411508  mov    dword ptr [ebp-60h],7FFFFFFFh  
  int value11 = ptrai[i][j];
0041150F  mov    eax,dword ptr [ebp-54h] копирование в еах переменной i, INT_MAX
00411512  mov    ecx,dword ptr [ebp-48h] копирование в еcх значения ptrai, у меня 0x0012ff50
00411515  lea    edx,[ecx+eax*8] загрузка еффективного адреса, то есть указателя на начало 1ой строки матрицы. Здесь хорошо видна первая часть матричной арифметики: 0x0012ff50 + 0х7FFFFFFF * 8 = 0x0012ff50 + 0х7FFFFFF8 = 0x0012ff48. *8 потому что длинна строки матрицы это 8 байт или 2 int'а. По большому счёту указатель теперь указывает на 8 байт "левее" в стек
00411518  mov    eax,dword ptr [ebp-60h] копирование в еах переменной j, INT_MAX
0041151B  mov    ecx,dword ptr [edx+eax*4]  
копирование в еcх значения которое находится по адресу edx+eax*4 = 0x0012ff48 + 0х7FFFFFFF * 4 = 0x0012ff44. Ещё на 4 байта "левее" в стек. К сожалению мне "повезло" и адрес оказался валидным. У меня здесь по чистой случайности оказалась перемення ptri, поэтому в ecx залилось её значение - адрес dummy 0x0012ff50.
0041151E  mov    dword ptr [ebp-6Ch],ecx копирование из ecx в переменную value11
 
Теперь думаю всё более-менее понятно. При попытке посчитать координату указатель перетёк несколько раз, первый раз при попытке посчитать адрес нужной строки, второй раз при высчитывании адреса элемента в строке.
2Lion: Называй как хочешь, суть от этого не меняется.
 
Зарегистрирован

Don't worry, be happy.
Ushwood
[ДжАдай]
Прирожденный Джаец

May the Force be with you


WWW Ё-мэйл

Пол:
Репутация: +562
Re: С++ Вопросы и ответы.
« Ответ #136 от 30.09.2012 в 06:24:55 »

Всем спасибо за помощь :).  
Я нашел решение, самое тупое и, по-видимому, самое простое: исходный линейный массив точек сортируется (один раз) по возрастанию номера ячейки, в которые они входят, а в трехмерный массив 50х50х50 заносятся только границы соответствующих областей массива точек. Все.
« Изменён в : 30.09.2012 в 06:25:21 пользователем: Ushwood » Зарегистрирован

Мои текущие переводы:
Червь арка 30, версия 24.03.24

jarni
[Гарный хлопец]
Прирожденный Джаец

Мне нечего сказать.


Ё-мэйл

Пол:
Репутация: +306
Re: С++ Вопросы и ответы.
« Ответ #137 от 30.09.2012 в 06:29:33 »

2Ushwood: Это не решение, а обход решения :). Ведь у тебя всё равно останутся неиспользованные ячейки, в которые ни одна точка не попадает.
Зарегистрирован

Don't worry, be happy.
Ushwood
[ДжАдай]
Прирожденный Джаец

May the Force be with you


WWW Ё-мэйл

Пол:
Репутация: +562
Re: С++ Вопросы и ответы.
« Ответ #138 от 30.09.2012 в 07:52:22 »

2jarni: нет, не останется. Ты обратил внимание, что я написал - теперь у меня массив lattice не четырехмерный, а трехмерный? int lattice[m][m][m]. При этом lattice[0][0][0] - число точек в ячейке (0,0,0), lattice[0][0][1] - суммарное число точек в ячейках (0,0,0) и (0,0,1) и т.д. Поскольку массив точек отсортирован, этой информации мне достаточно, чтобы получить доступ ко всем точкам, находящимся в интересующей меня ячейке. Я задаю номер ячейки (i,j,k), и нужные мне точки в отсортированном линейном массиве - от lattice[i][j][k-1] до latticce[i][j][k].
Вместо 15 гигабайт размер массива 600 килобайт. Профит :).
 
ЗЫ. то есть пустые ячейки пространства останутся, конечно, это свойство системы. Но если раньше пустая ячейка пространства - это было 30000 нулевых интов, то теперь - один инт. С точки зрения расхода памяти - две большие разницы :).
« Изменён в : 30.09.2012 в 08:00:06 пользователем: Ushwood » Зарегистрирован

Мои текущие переводы:
Червь арка 30, версия 24.03.24

Korchy
[Непреодолимая сила]
Прирожденный Джаец

Ах, было б только с кем поговорить ...


WWW Ё-мэйл

Пол:
Репутация: +663
Re: С++ Вопросы и ответы.
« Ответ #139 от 30.09.2012 в 17:47:24 »

2jarni:  
Я не совсем понял, что ты доказал примером, но я согласен, задача адресовать массив больше MAX_INT так просто не решается. И раз Юра такую задачу не ставит и нашел решение с маленьким массивом, ломать голову над этим не нужно. Хотя где-то на задворках сознания сидит мысля, что это все-таки возможно реализовать (но я на ней не настаиваю потому, что раньше такого не решал).
« Изменён в : 30.09.2012 в 17:48:22 пользователем: Korchy » Зарегистрирован

ban.gif
jarni
[Гарный хлопец]
Прирожденный Джаец

Мне нечего сказать.


Ё-мэйл

Пол:
Репутация: +306
Re: С++ Вопросы и ответы.
« Ответ #140 от 30.09.2012 в 21:22:34 »

2Korchy: Первая часть примера показывает что изменение типа указателя не меняет размер указателя и соответственно не позволяет адресовать больше а совсем даже наоборот, вторая часть показывает как возникает перетечение указательной арифметики и что это не обязтельно свалится с исключением которое бы указало что что-то не так.
 
 30.09.2012 в 17:47:24, Korchy писал(a):
задача адресовать массив больше MAX_INT так просто не решается
Ну почему же, решается очень просто аж до MAX_UINT. Вообще мне кажется немного некорректным использовать для индекса знаковые целые ведь индекс всегда >=0.
Зарегистрирован

Don't worry, be happy.
Korchy
[Непреодолимая сила]
Прирожденный Джаец

Ах, было б только с кем поговорить ...


WWW Ё-мэйл

Пол:
Репутация: +663
Re: С++ Вопросы и ответы.
« Ответ #141 от 30.09.2012 в 22:05:33 »

2jarni:  
 30.09.2012 в 21:22:34, jarni писал(a):
Первая часть примера показывает что изменение типа указателя не меняет размер указателя и соответственно не позволяет адресовать больше а совсем даже наоборот

Да, с этим согласен, я поторопился.
 
 30.09.2012 в 21:22:34, jarni писал(a):
Ну почему же, решается очень просто аж до MAX_UINT

Это тоже самое. Я имел ввиду выход за эти пределы.
Зарегистрирован

ban.gif
Korchy
[Непреодолимая сила]
Прирожденный Джаец

Ах, было б только с кем поговорить ...


WWW Ё-мэйл

Пол:
Репутация: +663
Re: С++ Вопросы и ответы.
« Ответ #142 от 18.04.2013 в 01:49:39 »

Вопрос не совсем по С++, но не знаю, куда его загнать, а отдельной темы создавать явно смысла не имеет.
Задача такая: есть слово. Например MNEMONIKA. И есть условие поиска, например *MN*NIK* по которому слово находится. Нужно определить наибольшее кол-во совпавших символов и позиции совпавших фрагментов. Для данного примера ответ будет 1 (позиция) - 2 (кол-во совпадений), 6 - 3. В принципе алгоритм прост: последовательно фрагменты между звездочек двигаем по полному слову, считаем кол-во совпадений символов, максимальные значения запоминаем.
Проблем: сколько звездочек поставил пользователь в поиске заранее не известно. Считается при вызове процедуры поиска diff("*MN*NIK*","MNEMONIKA");
Вопрос: возможно ли организовать алгоритм циклами для динамического кол-во звездочек. Проблема №2: использовать массивы и динамические переменные нельзя - нужна процедура на языке MySQL, он динамику не поддерживает.
Я пока решил, что больше пяти фрагментов (4 звездочек) - это бред и тупо вложенными циклами сделал сканирование для пяти кусков.
Но хотелось бы понять, можно ли придумать алгоритм без массивов для любого кол-ва звездочек.
« Изменён в : 18.04.2013 в 01:50:42 пользователем: Korchy » Зарегистрирован

ban.gif
Artem13
[13-й воин]
Прирожденный Джаец

Ап, и черти у ног моих сели...


WWW Ё-мэйл

Пол:
Репутация: +441
Re: С++ Вопросы и ответы.
« Ответ #143 от 04.06.2013 в 20:43:29 »

Нужно простое динамическое хранилище для составных данных (struct известного размера). Попытался использовать vector, но билдер ругается на отсутствующий тип (хотя тип структуры объявлен ранее).  
 
typdef struct { ...} Abonent;
 
vector<Abonent> AbonentList;
 
ЧЯДНТ? Вся литература дома осталась, подглядеть негде :(
Зарегистрирован

Artem13.gif
http://www.aap13.narod.ru
И пули, что найдет тебя,
Ты не услышишь,
А остальные мимо пролетят

jarni
[Гарный хлопец]
Прирожденный Джаец

Мне нечего сказать.


Ё-мэйл

Пол:
Репутация: +306
Re: С++ Вопросы и ответы.
« Ответ #144 от 04.06.2013 в 20:48:22 »

2Artem13: А ты уверен что ругается на незнание Abonent'а? Может ты просто забыл std:: перед vector написать? У меня никаких проблем в ВС2008.
 
 04.06.2013 в 20:43:29, Artem13 писал(a):
Вся литература дома осталась
Гугл тебя забанил? :)
Зарегистрирован

Don't worry, be happy.
Artem13
[13-й воин]
Прирожденный Джаец

Ап, и черти у ног моих сели...


WWW Ё-мэйл

Пол:
Репутация: +441
Re: С++ Вопросы и ответы.
« Ответ #145 от 04.06.2013 в 21:20:15 »

04.06.2013 в 20:48:22, jarni писал(a):
Может ты просто забыл std:: перед vector написать?

Это мысля! Ща попробую.
 
 04.06.2013 в 20:48:22, jarni писал(a):
Гугл тебя забанил?

Время мало - на моём рабочем компе нет инета, приходится на общий бегать.
 
Я просто СТЛ юзаю от случая к случаю, которые очень редки :)
Зарегистрирован

Artem13.gif
http://www.aap13.narod.ru
И пули, что найдет тебя,
Ты не услышишь,
А остальные мимо пролетят

jarni
[Гарный хлопец]
Прирожденный Джаец

Мне нечего сказать.


Ё-мэйл

Пол:
Репутация: +306
Re: С++ Вопросы и ответы.
« Ответ #146 от 04.06.2013 в 21:23:06 »

2Artem13:  04.06.2013 в 21:20:15, Artem13 писал(a):
на моём рабочем компе нет инета
Ух как всё грустно :(.  
 
Если добавка стд:: не помогла то было бы хорошо если бы ты скопировал сюда текст ошибки.
Зарегистрирован

Don't worry, be happy.
Artem13
[13-й воин]
Прирожденный Джаец

Ап, и черти у ног моих сели...


WWW Ё-мэйл

Пол:
Репутация: +441
Re: С++ Вопросы и ответы.
« Ответ #147 от 04.06.2013 в 21:49:25 »

2jarni: Не, помогло. Большое спасибо!
Зарегистрирован

Artem13.gif
http://www.aap13.narod.ru
И пули, что найдет тебя,
Ты не услышишь,
А остальные мимо пролетят

Artem13
[13-й воин]
Прирожденный Джаец

Ап, и черти у ног моих сели...


WWW Ё-мэйл

Пол:
Репутация: +441
Re: С++ Вопросы и ответы.
« Ответ #148 от 23.07.2013 в 21:47:38 »

Други, нужен совет.
ИД: Есть расширяющаяся номенклатура приборов. Приборы поддерживают обмен по протоколу Modbus. Для каждого нового прибора мне приходится писать новую программу для работы с ним по цифровому интерфейсу.
Задача: написать б-м универсальную программу хотя бы для визуализации принятых с прибора данных. На данный момент я вижу один способ - во внеш. конфигурационных файлах описывать данные, получаемые с каждого типа приборов (доступное адресное пространство, название тип данных по определённым адресам).
Собсно, может кто предложить другой вариант. Если нет, то по озвученному - для конфиг-файлов использовать хml, ini или еще что?
Зарегистрирован

Artem13.gif
http://www.aap13.narod.ru
И пули, что найдет тебя,
Ты не услышишь,
А остальные мимо пролетят

jarni
[Гарный хлопец]
Прирожденный Джаец

Мне нечего сказать.


Ё-мэйл

Пол:
Репутация: +306
Re: С++ Вопросы и ответы.
« Ответ #149 от 23.07.2013 в 21:56:33 »

2Artem13: Тоже не вижу другого варианта кроме конфига. Универсальный способ без надобности перекомпиляции. А тип конфига выбирай из собственных преференций, что тебе легче парсить, важен ли размер файла, надо ли будет делать над конфигом какие-то другие операции вроде выборки подможеств параметров, надо ли удобство создания когфига и т.д.
Зарегистрирован

Don't worry, be happy.
Страниц: 1 2 3 4 5 6 7  Послать Тему Послать Тему Печатать Печатать

« Предыдущая Тема | Следующая Тема »

Статистика. Размер данных: 176104 GZip: off
A.I.M. » Powered by YaBB Modification 4 (v.4.0.0-pre)!
YaBB © 2000-2003. All Rights Reserved.