Почему был бы, waveOutWrite () вызывают исключение в "куче" отладки?

var array = [1,2,3,4];
var anotherOne = [2,4];
var filteredArray = array.filter(myCallBack);

function myCallBack(el){
  return anotherOne.indexOf(el) < 0;
}

В обратном вызове вы проверяете, находится ли каждое значение array в anotherOne

https://jsfiddle.net/0tsyc1sx/

Если вы используете lodash.js, используйте _.difference

filteredArray = _.difference(array, anotherOne);

Demo

Если у вас есть массив объектов:

var array = [{id :1, name :"test1"},{id :2, name :"test2"},{id :3, name :"test3"},{id :4, name :"test4"}];

var anotherOne = [{id :2, name :"test2"}, {id :4, name :"test4"}];

var filteredArray  = array.filter(function(array_el){
   return anotherOne.filter(function(anotherOne_el){
      return anotherOne_el.id == array_el.id;
   }).length == 0
});

Демо-массив объектов

Demo diff array объектов с lodash

13
задан 7 revs 23 October 2008 в 21:50
поделиться

8 ответов

Вы не являетесь одними с этой проблемой: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=100589

2
ответ дан 2 December 2019 в 01:57
поделиться

Теперь, причина, что GlobalHandle () бомбы не происходит из-за повреждения "кучи", поскольку я подозревал сначала - это - потому что waveOutWrite () возвратился, не устанавливая первый указатель во внутренней структуре к допустимому указателю. Я подозреваю, что это освобождает память, на которую указывает тот указатель перед возвратом, но я еще не демонтировал его.

Я могу воспроизвести это с Вашим кодом моей системы. Я вижу что-то подобное тому, о чем сообщил Johannes. После того, как вызов к WaveOutWrite, hdr-> зарезервированный обычно содержит указатель на выделенную память (который, кажется, содержит волновое название устройства вывода в unicode, среди прочего).

Но иногда, после возврата из WaveOutWrite (), байт, которым указывают hdr->reserved установлен на 0. Это обычно - младший значащий байт того указателя. Остальная часть байтов в hdr->reserved в порядке, и блок памяти, на которую он обычно указывает, все еще выделяется и не повреждается.

Это, вероятно, ударяется другим потоком - я могу поймать изменение с условной точкой останова сразу после вызова к WaveOutWrite (). И системная точка останова отладки происходит в другом потоке, не обработчике сообщений.

Однако я не могу заставить системную точку останова отладки происходить, если я использую функцию обратного вызова вместо насоса сообщения окон. (fdwOpen = CALLBACK_FUNCTION в WaveOutOpen ()), Когда я делаю это этот путь, мой обработчик OnWOMDone называет другой поток - возможно тот, который это в других отношениях ответственно за повреждение.

Таким образом, я думаю, что существует ошибка, или в окнах или в драйвере, но я думаю, что можно работать вокруг путем обработки WOM_DONE с функцией обратного вызова вместо насоса сообщения окон.

3
ответ дан 2 December 2019 в 01:57
поделиться

Не уверенный в этой конкретной проблеме, но Вы рассмотрели использование высокоуровневой, межплатформенной аудио библиотеки? Существует много причуд с программированием аудио Windows, и эти библиотеки могут сохранить Вас много головных болей.

В качестве примера можно привести PortAudio, RtAudio, и SDL.

0
ответ дан 2 December 2019 в 01:57
поделиться

Первая вещь, которую я сделал бы, будет состоять в том, чтобы проверить возвращаемые значения от функций waveOutX. Если какой-либо из них перестал работать - который не неблагоразумен, учитывая сценарий, который Вы описываете - и Вы продолжаете независимо тогда, не удивительно, что вещи начинают идти не так, как надо. Мое предположение было бы то, что waveOutWrite возвращает MMSYSERR_NOMEM в какой-то момент.

0
ответ дан 2 December 2019 в 01:57
поделиться

Используйте Верификатор Приложения для выяснения то, что продолжается, если Вы сделаете что-то подозрительное, то он поймает его намного ранее.

0
ответ дан 2 December 2019 в 01:57
поделиться

Может быть полезно посмотреть на исходный код для Вина, хотя возможно, что Вино исправило любую ошибку существует, и это - также возможное Вино, имеет другие ошибки в нем. Соответствующие файлы являются dlls/winmm/winmm.c, dlls/winmm/lolvldrv.c, и возможно другими.Удачи!

0
ответ дан 2 December 2019 в 01:57
поделиться

Я вижу ту же проблему и сделал некоторый анализ сам:

waveOutWrite () выделяет (т.е. GlobalAlloc) указатель на область "кучи" 354 байтов и правильно хранит его в области данных, на которую указывает header.reserved.

Но когда эта область "кучи" должна быть освобождена снова (в waveCompleteHeader (), согласно Вашему анализу; у меня нет символов для wdmaud.drv самого), младший значащий байт указателя был обнулен, таким образом делая недействительным указатель (в то время как "куча" еще не повреждается). Другими словами, что происходит, что-то как:

  • (БАЙТ *) (header.reserved) = 0

Таким образом, я не соглашаюсь с Вашими операторами в одной точке: waveOutWrite () хранит допустимый указатель сначала; указатель только становится поврежденным позже от другого потока. Вероятно, это - тот же поток (mxdmessage), что более поздние попытки освободить эту область "кучи", но я еще не нашел точку, где нулевой байт хранится.

Этого не происходит очень часто, и та же область "кучи" (тот же адрес) была успешно выделена и освобождена прежде. Я вполне убежден, что это - ошибка где-нибудь в системном коде.

1
ответ дан 2 December 2019 в 01:57
поделиться

А как насчет того, что вам не разрешено вызывать функции winmm из обратного вызова? MSDN не упоминает такие ограничения для оконных сообщений, но использование оконных сообщений аналогично функции обратного вызова. Возможно, внутренне он реализован как функция обратного вызова от драйвера, и этот обратный вызов выполняет SendMessage. Внутри waveout должен поддерживать связанный список заголовков, которые были написаны с помощью waveOutWrite; Итак, я предполагаю, что:

hdr->reserved = (Undocumented*)calloc(sizeof(Undocumented));

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

В нескольких источниках в Интернете упоминается, что вам не нужно не готовить одни и те же заголовки несколько раз. Если вы закомментируете заголовок Prepare / unprepare в исходном примере, он будет работать нормально без каких-либо проблем.

0
ответ дан 2 December 2019 в 01:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: