C ++ Какое максимальное количество байтов можно динамически распределить с помощью оператора new в Windows XP с использованием VS2005? - PullRequest
0 голосов
/ 08 февраля 2009

У меня есть код на c ++, который пытается динамически выделить 2d массив байтов размером примерно 151 МБ. Когда я пытаюсь вернуться назад и проиндексировать массив, моя программа каждый раз вылетает в одном и том же месте с ошибкой «Ошибка чтения места доступа 0x0110f000», но индикаторы находятся в диапазоне. Это заставляет меня поверить, что память на этих признаках была распределена неправильно.

1) Какое максимальное количество байтов вы можете динамически выделить с помощью оператора new?

2) Если это случай, когда мне не удается динамически распределить память, имеет ли смысл, что мой код дает сбой при попытке доступа к массиву с точно одинаковыми двумя индикаторами каждый раз? Почему-то я чувствую, что они будут отличаться при каждом запуске программы, но что я знаю;)

3) Если вы не думаете, что проблема связана с неудачным вызовом нового, есть какие-либо другие идеи, которые могут быть причиной этой ошибки и сбоя?

Заранее спасибо за вашу помощь!

* Edit

Вот мой код для выделения 2d массива ...

#define HD_WIDTH 960
#define HD_HEIGHT 540
#define HD_FRAMES 100

//pHDVideo is a char**
pHDVideo->VideoData = new char* [HD_FRAMES];

for(int iFrame = 0; iFrame < HD_FRAMES; iFrame++)
{
    //Create the new HD frame
    pHDVideo->VideoData[iFrame] = new char[HD_WIDTH * HD_HEIGHT * 3];
    memset(pHDVideo->VideoData[iFrame], 0, HD_WIDTH * HD_HEIGHT * 3);
}

и вот скриншот кода сбоя и отладчика (Dead Link), это поможет.

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

EDIT Я нашел решение всем, спасибо за вашу помощь. Каким-то образом, и мне все еще нужно выяснить, как была увеличена одна горизонтальная линия, поэтому я изменился ...

for(int iHeight = 0; iHeight < HD_HEIGHT; iHeight++)

до

for(int iHeight = 0; iHeight < HD_HEIGHT-1; iHeight++)

и это вдруг сработало. В любом случае, большое спасибо еще раз!

Ответы [ 5 ]

4 голосов
/ 08 февраля 2009

Некоторые возможности посмотреть или попробовать:

  • Возможно, что где-то освобождается pHDVideo-> VideoData [iFrame] или pHDVideo-> VideoData. Я сомневаюсь, что это так, но я бы все равно проверил, где это может случиться. Выводите оператор отладки каждый раз, когда вы освобождаетесь от этих операторов И непосредственно перед оператором сбоя.
  • Возможно, что-то перезаписывает значения pHDVideo-> VideoData [iFrame]. Распечатайте их, когда они выделены, и непосредственно перед вашим заявлением о сбое, чтобы увидеть, изменились ли они. Если 0x0110f000 не находится в пределах диапазона одного из них, это почти наверняка так.
  • Возможно, что-то перезаписывает значение pHDVideo. Распечатайте его, когда выделите, и непосредственно перед вашим заявлением о сбое, чтобы увидеть, изменилось ли оно. Это зависит от того, что еще находится в вашей структуре pHDVideo.
  • Пожалуйста, покажите нам код, который дает сбой, с достаточным количеством контекста, чтобы мы могли это проверить.

В ответ на ваши конкретные вопросы:

1 / Это зависит от реализации или платформы, и в данном случае это не имеет значения. Если ваши новые сбои, вы получите исключение или нулевой возврат, а не хитрый указатель.

2 / Дело не в этом: см. (1).

3 / Смотрите выше некоторые возможности и вещи, чтобы попробовать.

После добавления вашего скриншота:

Вы понимаете, что сообщение об ошибке гласит: "Нарушение доступа чтение ..."?

Это означает, что он не жалуется на запись в pHDVideo->VideoData[iFrame][3*iPixel+2], а на чтение из this->VideoData[iFrame][3*iPixelIndex+2].

iPixelIndex установлен на 25458, так что вы можете подтвердить, что this->VideoData[iFrame][76376] существует? Я не вижу на вашем скриншоте, как это-> VideoData распределяется и заполняется.

3 голосов
/ 08 февраля 2009

Как вы получаете доступ к выделенной памяти? Всегда ли умирает от одного и того же утверждения? Это выглядит очень похоже на то, что вы бежите от конца либо одномерного массива указателей, либо от одного из больших блоков символов, на которые он указывает. Как вы говорите, memset в значительной степени доказывает, что память была выделена правильно. Общий объем памяти, который вы выделяете, составляет около 0x9450C00 байт, поэтому указанный вами адрес находится за пределами выделенной памяти, если он был выделен случайно.

Ваш снимок экрана показывает, что iPixel находится в пределах досягаемости, но не показывает, каково было значение iFrame. Это вне диапазона 0-99?

Обновление: ошибка не в распределении памяти, а в преобразовании координат HD в SD. Значение, которое вы читаете из буфера SD, находится вне диапазона, потому что оно находится в координатах (144,176), а не в диапазоне (0,0) - (143,175).

2 голосов
/ 08 февраля 2009

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

Нет, для меня это не имеет смысла.

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

1 голос
/ 08 февраля 2009

Почему вы используете математику с плавающей запятой для вычисления целочисленного индекса?

Похоже, вы индексируете вне диапазона буфера изображения SD. 25344 == SD_WIDTH * SD_HEIGHT, что меньше, чем iPixelIndex, 25458.

0 голосов
/ 08 февраля 2009

Обратите внимание, что выделение кучи (например, с использованием new) эффективно при выделении множества небольших объектов (именно поэтому это куча). Если у вас очень большие объемы памяти, лучше использовать VirtualAlloc и друзей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...