Как зайти в Даркнет?!
25th January, 01:11
4
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
892
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
912
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4380
0
Помогите пожалуйста решить задачи
24th November, 23:53
6084
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4350
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4395
0
Метода Крамера С++
23rd October, 11:55
4308
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2598
0
memset() причина прерывания передачи данных
Я получаю некоторые странные, прерывистые, прерывания данных (< 5% времени) в некоторых моих кодах, когда вызываю memset() . Проблема в том, что обычно это не происходит, если код не работает в течение нескольких дней, поэтому его трудно поймать в действии.
Я использую следующий код:
char *msg = (char*)malloc(sizeof(char)*2048);
char *temp = (char*)malloc(sizeof(char)*1024);
memset(msg, 0, 2048);
memset(temp, 0, 1024);
char *tempstr = (char*)malloc(sizeof(char)*128);
sprintf(temp, "%s %s/%s %s%s", EZMPPOST, EZMPTAG, EZMPVER, TYPETXT, EOL);
strcat(msg, temp);
//Add Data
memset(tempstr, '\0', 128);
wcstombs(tempstr, gdevID, wcslen(gdevID));
sprintf(temp, "%s: %s%s", "DeviceID", tempstr, EOL);
strcat(msg, temp);
Как вы можете видеть, я не пытаюсь использовать memset с размером больше, чем то, что изначально выделено с malloc()
Кто-нибудь видит, что может быть не так с этим?
Есть еще пара вещей. Вы используете sprintf , что само по себе небезопасно; если вы не уверены, что 100% не превысит размер буфера, вы почти всегда должны предпочесть snprintf . То же самое относится и к strcat ; предпочитайте более безопасную альтернативу strncat .
Очевидно, что это может ничего не исправить, но это очень помогает обнаружить то, что в противном случае может быть очень раздражающим для обнаружения ошибок.
malloc может вернуть NULL, если память отсутствует
доступный. Ты же не проверяешь его на наличие
тот.
malloc может вернуть NULL, если память отсутствует доступный. Ты же не проверяешь его на наличие тот.
Да, вы правы... Я не думал об этом, так как следил за памятью, и она была достаточно свободной. Есть ли какой-либо способ для того, чтобы в системе была доступная память, но для malloc произошел сбой?
Да, если память фрагментирована. Кроме того, когда вы говорите "monitoring memory,", в системе может быть что-то, что иногда потребляет много памяти, а затем освобождает ее, прежде чем вы заметите. Если ваш вызов
mallocпроизойдет тогда, то не будет никакой доступной памяти. -- Джоул
Либо way...I добавлю, что проверить :)
wcstombs не получает размер места назначения,поэтому теоретически он может быть переполнен буфером.
И почему вы используете sprintf с тем, что я предполагаю, является константами? Просто использовать:
EZMPPOST" " EZMPTAG "/" EZMPVER " " TYPETXT EOL
C и C++ объединяет объявления строковых литералов в одну строку.
Вы используете sprintf который является
по своей сути небезопасно; если только вы не 100%
уверен, что ты этого не сделаешь
превышая размер буфера, вы
следует почти всегда отдавать предпочтение snprintf.
То же самое относится и к strcat; предпочитайте
более безопасная альтернатива strncat.
Вы используете sprintf который является по своей сути небезопасно; если только вы не 100% уверен, что ты этого не сделаешь превышая размер буфера, вы следует почти всегда отдавать предпочтение snprintf. То же самое относится и к strcat; предпочитайте более безопасная альтернатива strncat.
Да..... В последнее время я в основном делаю .NET, и старые привычки умирают с трудом. Вероятно, я вытащил этот код из чего-то другого, что было написано до меня...
Но я постараюсь не использовать их в будущем ;)
Это может быть ваш процессор. Некоторые CPUs не могут обращаться к отдельным байтам и требуют, чтобы вы работали в словах или размерах фрагментов, или имеют инструкции, которые могут использоваться только для выровненных по словам или фрагментам данных.
Обычно компилятор осознает это и работает вокруг них, но иногда вы можете malloc область как байт, а затем попытаться адресовать ее как структуру или поле wider-than-a-byte, и компилятор не поймает ее, но процессор позже выдаст исключение данных.
Это не произойдет, если вы не используете необычный CPU. Обработчик ARM9 будет этого делать, например, но i686 в не. Я вижу, что он помечен windows мобильного, так что, возможно, у вас есть эта проблема CPU.
НБ заимствовал некоторые комментарии из других ответов и интегрировал их в единое целое. Этот код полностью принадлежит мне...
- Проверьте свои коды ошибок. E.g. malloc может вернуть NULL, если нет доступной памяти. Это может привести к прерыванию передачи данных.
- sizeof (char) по определению равен 1
- Используйте snprintf а не sprintf чтобы избежать переполнения буфера
- Если EZMPPOST и т. д. являются константами, то вам не нужна строка формата, вы можете просто объединить несколько строковых литералов как STRING1 ""STRING2 "" STRING3 и strcat весь лот.
- Вы используете гораздо больше памяти, чем вам нужно.
- С одним незначительным изменением, вам не нужно вызывать memset в первую очередь. Ничего здесь действительно требуется нулевая инициализация.
Этот код делает то же самое, безопасно, работает быстрее и использует меньше памяти.
// sizeof(char) is 1 by definition. This memory does not require zero
// initialisation. If it did, I'd use calloc.
const int max_msg = 2048;
char *msg = (char*)malloc(max_msg);
if(!msg)
{
// Allocaton failure
return;
}
// Use snprintf instead of sprintf to avoid buffer overruns
// we write directly to msg, instead of using a temporary buffer and then calling
// strcat. This saves CPU time, saves the temporary buffer, and removes the need
// to zero initialise msg.
snprintf(msg, max_msg, "%s %s/%s %s%s", EZMPPOST, EZMPTAG, EZMPVER, TYPETXT, EOL);
//Add Data
size_t len = wcslen(gdevID);
// No need to zero init this
char* temp = (char*)malloc(len);
if(!temp)
{
free(msg);
return;
}
wcstombs(temp, gdevID, len);
// No need to use a temporary buffer - just append directly to the msg, protecting
// against buffer overruns.
snprintf(msg + strlen(msg),
max_msg - strlen(msg), "%s: %s%s", "DeviceID", temp, EOL);
free(temp);