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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> функции добавления/удаления эелементов из массива 
:(
    Опции темы
massiv
Дата 27.9.2009, 15:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Есть 2-е функции для работы с динамическими массивами (_push и _pop). Одна добавляет элемент в массив, другая удаляет элемент из массива. Вроде бы функции написаны правильно, и жаде делают то что нужно  smile  но, при использовании в многопоточной программе почему то дают сбой: функция добавления элемента Б во вторую ячейку почему то ИНОГДА (при определённых условиях, но не всегда) затирает первый элемент А массива, находящийся в первой ячейке, таким образом получается следующее:

1) есть массив с одним элементом : m = {A} (массив естественно динамический, это я для примера в фигурных пишу)
2) применяем функцию добавление элемента B в массив:  _push(m, massiv_size, B),
3) получаем массив m= {B,B}, а должен быть равен {A,B}

Собственно вопрос: почему так происходит? замечу что происходит так не всегда. Коды функций ниже:

_pop: 
Код

int _pop (int *mas, int msize, int pop_value) {     // на входе: ссылка на массив, его текущая размерность (число элементов), элемент который хотим вынуть из массива
  int i, j;
 
  for (i = 0, j = 0; i < msize; i++) { 
    if (mas[i] != pop_value) {
      mas[j] = mas[i];               //  перезаписываем все елементы кроме того который хотим убрать
      j++;
    }
  }

  if (!(mas = (int *) realloc(mas, (msize - 1) * sizeof(int)))) {            // и уменьшаем размерность массива на единицу
      perror("realloc");
      return -1;
    }

  return msize-1;           // на выходе новая размерность массива
}
 


_push
Код

int _push (int *mas, int msize, int push_value) {   // на входе: ссылка на массив, текущая размерность (число элементов), элемент который хотим добавить в массив
  if (!(mas = (int *) realloc(mas, (msize + 1) * sizeof(int)))) {   // увеличиваем массив на один элемент
    perror("perror");
    return -1;
  }

  mas[msize] = push_value;   // добавляем элемент

  return msize + 1;   // возвращаем новую размерность
}



Если что то не понятно объяснил, спрашивайте. В конце концов могу полный код привести если понадобится
PM MAIL   Вверх
Graf_h
Дата 27.9.2009, 16:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 482
Регистрация: 18.10.2007
Где: г. Ровно, Украина

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



massiv,  во первых, ставте критические секции на добавление и удаление, во вторых, не думаю что пробегатся фором  по всему масиву при перезаписи - это правильный выбор. 


--------------------
Иногда переменная - это просто переменная
PM MAIL ICQ   Вверх
massiv
Дата 27.9.2009, 17:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата

во первых, ставте критические секции на добавление и удаление


 не понимаю, поясните пож-ста

Цитата

во вторых, не думаю что пробегатся фором  по всему масиву при перезаписи - это правильный выбор. 



вы об этом участке в функции _push ?

  for (i = 0, j = 0; i < msize; i++) { 
    if (mas[i] != pop_value) {
      mas[j] = mas[i];              
      j++;
    }
  }

несколько способов перебрал...на мой взгляд этот самый простой и лаконичный для поиска и исключения заданного элемента  pop_value из массива, если есть проще, подскажите пожалуста


Я кажется понял что вы хотели сказать во втором, наверное на перезапись действительно может потратиться много времени особенно если массив большой, хорошо бы как то просто удалить этот элемент и сдвинуть массив,  как то вот так :

(A,B,C,D) -> (A, NULL, C, D) -> (A, C, D) 

но как это можно осуществить relloc-ом - непонятно....

Это сообщение отредактировал(а) massiv - 27.9.2009, 18:06
PM MAIL   Вверх
Graf_h
Дата 27.9.2009, 19:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 482
Регистрация: 18.10.2007
Где: г. Ровно, Украина

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



massiv,  функция memcpy или memmove 
http://c2p.ru/c/func/strokovye-i-simvolnye
Можна заюзать СТЛ контейнеры

Цитата(massiv @  27.9.2009,  15:31 Найти цитируемый пост)
при использовании в многопоточной программе

А чему вы удивляетесь? Представте себе ситуация когда два потока одновременно обращаются к вашим функциям...))

Цитата(massiv @  27.9.2009,  17:26 Найти цитируемый пост)
не понимаю, поясните пож-ста


http://ru.wikipedia.org/wiki/%D0%9A%D1%80%...%86%D0%B8%D1%8F

http://www.cyberguru.ru/programming/cpp/mu...ntro-page2.html



Это сообщение отредактировал(а) Graf_h - 27.9.2009, 19:36


--------------------
Иногда переменная - это просто переменная
PM MAIL ICQ   Вверх
massiv
Дата 27.9.2009, 22:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата

А чему вы удивляетесь? Представте себе ситуация когда два потока одновременно обращаются к вашим функциям...))


Нет, в том то и суть,  я защищаю участки использования этих функций мьютексами, так что в этом плане всё в порядке, я уверен.

Остальное сейчас почитаю.



Ага!на счёт критических секций, я уже ответил - использую мьютексы, STL контейнеры тоже отпадают, код написан на С и компиляется это всё под линуксом (забыл упомянуть)  smile 

Это сообщение отредактировал(а) massiv - 27.9.2009, 22:56
PM MAIL   Вверх
massiv
Дата 28.9.2009, 08:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Пытаюсь сделать с помощью memmove, но сталкиваюсь с проблемой :

Код

int _pop (int *mas, int msize, int pop_value) {  
  int i, j, *p;
  j = 0;

  p = (int *) malloc((msize - 1) * sizeof(int));

  for (i = 0; i < msize; i++) {

       if (mas[i] == pop_value) { 
     j = i;                          // находим индекс исключаемого элемента
         break;
       }
  }

  printf("->> index = %d\n\n", j);

  memmove(p, mas, sizeof(int) * j);        // копируем все элементы стоящие до исключаемого элемента

  for (i = 0; i < msize -1; i++) printf("%d ", p[i]);

  // mas = (int *) realloc(mas, (msize - 1) * sizeof(int));

  return msize -1;
}



Вопрос: как же скопировать остальные элементы, стоящие после исключаемого с помощью memmove?
PM MAIL   Вверх
MAKCim
Дата 28.9.2009, 09:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

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



Цитата(Graf_h @  27.9.2009,  16:50 Найти цитируемый пост)
то пробегатся фором  по всему масиву при перезаписи - это правильный выбор.  

для этого есть RCU
главное обеспечить барьеры перед изменением поинтера
хотя для массивов int и этого не надо


--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
Graf_h
Дата 28.9.2009, 09:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 482
Регистрация: 18.10.2007
Где: г. Ровно, Украина

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



massiv, 
Цитата(massiv @  28.9.2009,  08:06 Найти цитируемый пост)
Вопрос: как же скопировать остальные элементы, стоящие после исключаемого с помощью memmove? 

Елементы, которы стоят до исключаемого или добавляемого елемента трогать вообще не нужно. Нужно только сдвигать те, которые после.
realloc вам вообще не нужен. Сделайте как в СТЛ  векторе зарезервируйте количество памяти, и если елементов станет больше, выделите в 2 раз больше памяти (так называемое перераспредиление). На  мой взгляд - это логичней всего.
Код


memmove(p+index, mas, sizeof(int) * count); - примерно так


Это сообщение отредактировал(а) Graf_h - 28.9.2009, 09:30


--------------------
Иногда переменная - это просто переменная
PM MAIL ICQ   Вверх
Andrey44
Дата 28.9.2009, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

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



Цитата(massiv @  28.9.2009,  08:06 Найти цитируемый пост)
memmove(p, mas, sizeof(int) * j);        // копируем все элементы стоящие до исключаемого элемента

Цитата(Graf_h @  28.9.2009,  09:29 Найти цитируемый пост)
memmove(p+index, mas, sizeof(int) * count); - примерно так

Чем отличаются эти две строки?
Надо &mas[index] и sizeof(int) умножать на количество оставшихся элементов.
Как-то так



--------------------
????? ??, ??????? ?????.  smile 
PM MAIL WWW ICQ   Вверх
Graf_h
Дата 28.9.2009, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 482
Регистрация: 18.10.2007
Где: г. Ровно, Украина

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



Andrey44, там вообще не нужно променжуточного масива. 
Код

memmove(mas+index, mas+index+1, sizeof(int) * count); 


Это сообщение отредактировал(а) Graf_h - 28.9.2009, 17:27


--------------------
Иногда переменная - это просто переменная
PM MAIL ICQ   Вверх
Andrey44
Дата 28.9.2009, 14:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1501
Регистрация: 4.12.2006
Где: На работе

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



Цитата(Andrey44 @  28.9.2009,  12:49 Найти цитируемый пост)
memmove(p+index, mas, sizeof(int) * count); - примерно так

Но это-же ты писал?


--------------------
????? ??, ??????? ?????.  smile 
PM MAIL WWW ICQ   Вверх
Graf_h
Дата 28.9.2009, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 482
Регистрация: 18.10.2007
Где: г. Ровно, Украина

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



Andrey44, да)). поспешил. извиняюсь.

Это сообщение отредактировал(а) Graf_h - 28.9.2009, 14:25


--------------------
Иногда переменная - это просто переменная
PM MAIL ICQ   Вверх
massiv
Дата 28.9.2009, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



немного не так, вот как :

 memmove(mas+j, mas+j+1, (msize-j) *sizeof(int)); 

всем спасибо smile 

Это сообщение отредактировал(а) massiv - 28.9.2009, 17:07
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.0546 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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