у меня есть структура malloc () 'd, и после использования их, я хочу освободить () его, но моя программа замораживается здесь. Кто-либо может сказать мне, что я делаю неправильно?
Вот мой код:
struct data
{
char *filename;
char *size;
};
//primarypcs is a long type variable
struct data *primary = (struct data *)malloc( primarypcs * sizeof( struct data ) );
memset( primary, 0, sizeof(struct data *) * primarypcs );
...
...
...
for ( i = 0; i < primarypcs; i++ )
{
free( primary[i].filename ); //<----my program freezes here
free( primary[i].size ); //<----or here
}
free( primary );
Заранее спасибо!
kampi
Править:
Как может я правильно malloc память для имени файла и размера?
EDIT2:
Извините, но я спешил, и я не сделал сказал Вам всю информацию, что Вам нужно. Позвольте мне сделать это теперь :) Basicly, я хочу, создают приложение, которое получает список файлов двух данных дисков/папок и затем сравнивает их. Я думал (и все еще сделал), что самый легкий путь, когда я храню имена файлов, и их размер в структуре любят упомянутый выше. Таким образом, я должен выделить память динамично (я думаю это, что они называют ею) для имени файла и размера и трупа для структуры также.
Вы не представляете весь код, где много чего может пойти не так, но одна ошибка уже очевидна. Строка
memset( primary, 0, sizeof(struct data *) * primarypcs );
не делает того, что вы думаете. Она не обнуляет весь массив из-за ошибки типа в sizeof
. Скорее всего, в sizeof
предполагалось, что это
memset( primary, 0, sizeof(struct data) * primarypcs );
Note no *
. Из-за этой ошибки большинство указателей в массиве содержат в качестве исходных значений мусор. Если вы не установите их в нечто значимое в пропущенном коде, то при обращении к free
будут получены мусорные аргументы и произошла ошибка.
В общем, чтобы уменьшить вероятность таких ошибок, лучше избегать упоминания имен типов в вашей программе, кроме как в объявлениях. Так как ваш вопрос помечен как Си++ (хотя он наверняка выглядит как Си), то избавиться от каста типов на malloc
невозможно, но в противном случае я бы сказал, что следующее выглядит лучше
struct data *primary = (struct data *) malloc( primarypcs * sizeof *primary );
memset( primary, 0, primarypcs * sizeof *primary );
И, как заметка на полях, Если бы ваш код был задуман как Си++, то такой же результат можно было бы получить гораздо более элегантным, компактным и портативным способом
data *primary = new data[primarypcs]();
Конечно, в этом случае вам придется разбираться с памятью, используя соответствующую функциональность C++, а не free
.
Как выделены строки в структуре? Если они статически присваиваются константам, то не освобождайте их так, и все, что нужно, - это бесплатно ;
, освобождающих что-то, что не было MALLOC
Если строковые указатели установлены MALLOC () или CALLOC (), это правильно.
Для перезагрузки текущей страницы можно вызвать window.location.reload (true) . Он игнорирует все кэшированные элементы и извлекает новые копии страницы, css, изображений, JavaScript и т.д. с сервера. Это не очищает весь кэш, но приводит к очистке кэша для страницы, на которой вы находитесь.
Однако лучшей стратегией является версия пути или имени файла, как указано в различных других ответах. Кроме того, см. Revving Filenames: не используйте строку запросов по причинам, не использующим ? v = n
в качестве схемы управления версиями.
Вы не представляете весь код, где многое может пойти не так, но одна ошибка уже очевидна. Линия
memset( primary, 0, sizeof(struct data *) * primarypcs );
делает не то, что вы думаете, она делает. Он не обнуляет весь массив из-за ошибки типа в sizeof
. Скорее всего, это должно было быть
memset( primary, 0, sizeof(struct data) * primarypcs );
Примечание No *
под размером
. Из-за этой ошибки большинство указателей в массиве содержат мусор в качестве начальных значений. Если не задать для них что-то значимое в пропущенном коде, вызовы free
получат мусорные аргументы и завершатся неудачей.
Вообще, чтобы уменьшить вероятность таких ошибок, лучше всего избегать упоминания имен типов в вашей программе, за исключением объявлений. Так как ваш вопрос помечен C++ (хотя он наверняка выглядит как C), невозможно избавиться от отливок типа на malloc
, но в противном случае я бы сказал, что следующее выглядит лучше
struct data *primary = (struct data *) malloc( primarypcs * sizeof *primary );
memset( primary, 0, primarypcs * sizeof *primary );
И, в качестве побочной ноты, если ваш код должен был быть C++, вы можете получить тот же результат в гораздо более элегантном, компактный и портативный
data *primary = new data[primarypcs]();
Конечно, в этом случае вам придется освободить память, используя соответствующую функциональность C++ вместо free
.
Замена цикла for в нижней части кода на free (primary);
должна работать.
SWF-файлы Flash могут быть встроены в PDF-документ программным способом. Ознакомьтесь с библиотекой PDF от webSupergoo . Документация содержит примеры в C # и VB.NET.
-121--4436261-Ошибка в Internet Explorer .
Вы НЕ МОЖЕТЕ задать атрибут имени элемента ANY в IE, используя стандартный метод DOM .setAttribute ('имя', значение);
В IE (до версии 8, работающей в режиме стандартов IE8) этот метод не будет работать для установки атрибута имени.
Необходимо использовать одно из следующих действий:
//A (any browser)
var iframe = document.createElement('iframe');
iframe.name = 'frame_x';
//B (only in IE)
var iframe = document.createElement('<iframe name="frame_x"/>');
//C (use a JS library that fixes the bug (e.g. jQuery))
var iframe = $('<iframe name="frame_x"></iframe>');
//D (using jQuery to set the attribute on an existing element)
$('iframe:first').attr('name','frame_x');
-121--1275017- Если вы делаете это в C++, вы (почти наверняка) не должны использовать что-то вроде:
data *primary = new data[primarypcs]();
Вместо этого следует использовать что-то вроде:
struct data {
std::string filename;
std::string size;
};
std::vector<data> primary(primarypcs);
В этом случае управление памятью обычно выполняется гораздо проще: определите вектор в области, где он необходим, и когда он выйдет из области, память будет освобождена автоматически.
Использование массива new (например, new x [y]
) в C++ - это то, без чего вам лучше обойтись. Когда-то (15 лет назад или около того) это был почти единственный доступный инструмент, так что его (обиды) использование было почти неизбежным - но этот день уже давно, и это было, наконец, 10 лет, так как был действительно хороший повод использовать его.
Поскольку неизбежно есть комментарий о "кроме как в реализации чего-то вроде вектора", я отмечу, что нет, даже когда вы реализуете вектор, вы не используете новый массив - вы (косвенно, через распределитель) используете :: оператор new
для выделения необработанной памяти, размещение нового для создания объектов в этой памяти, и явные вызовы dtor для уничтожения объектов.
Это потому, что вы явно не выделили память для имени файла
и размера
. Таким образом, попытка сделать free( primary[i].filename );
или free( primary[i].size );
вызовет Undefined Behavior.
Достаточно только free(primary)
.
EDIT:
Этот вопрос был помечен C++. Таким образом, путь C++ заключается в использовании new
вместо malloc
для определенных пользователем типов.
Для различий между новым
и malloc
посмотрите на .
В C++ нужно просто написать
data *primary = new data[primarypcs](); //() for value initialization
Вы не можете измерить весь массив, приводящий к освобождению памяти мусора. Используйте Calloc вместо Mailloc / Memet, чтобы избежать этой ошибки:
struct data *primary = calloc(primarypcs, sizeof(struct data));
это оба выделяется и очищает память.
Если вы хотите инициализировать все данные данных структуры
:
for (i = 0; i < primarypcs; ++i) {
primary[i].filename = malloc(...);
primary[i].size = malloc(...);
}
(вы не описываете, какое значение имена файла есть, поэтому я оставляю ... в том, чтобы вы заполнить).
Это исправляет вашу проблему в мемсете, которая вызвала у вас всевозможные проблемы.
memset( primary, 0, sizeof(struct data) * primarypcs );
Короче говоря, вы оставили неинициализированную память в конце вашей "первичной" структуры.
Как уже говорили другие, в показанном вами фрагменте есть две явно неправильные вещи:
filename
и size
только что выделенных структур, memset ()
использует неправильный размер. Ваш вызов memset ()
можно упростить и исправить следующим образом:
memset(primary, 0, primarypcs * sizeof *primary);
Есть еще одна тонкая проблема с вашим кодом: стандарт C не гарантирует, что все-биты-ноль являются константой нулевого указателя. (т.е. NULL), поэтому memset () - неправильный способ установки указателя на NULL
. Переносимый способ сделать то, что вы хотите сделать:
size_t i;
for (i=0; i < primarypcs; ++i) {
primary[i].filename = NULL;
primary[i].size = NULL;
}
Чтобы выделить память для filename
и size
, это зависит от того, что вы хотите. Допустим, вы определили, что для filename
требуется n
байтов, а для size
требуется m
. Затем ваш цикл изменится на что-то вроде этого:
size_t i;
for (i=0; i < primarypcs; ++i) {
size_t n, m;
/* get the values of n and m */
primary[i].filename = malloc(n * sizeof *primary[i].filename);
primary[i].size = malloc(m * sizeof *primary[i].size);
}
Вы можете опустить умножение на sizeof * primary [i] .filename
и sizeof * primary [i] .size
из выше, если вы хотите: C гарантирует, что sizeof (char)
равно 1.Я написал выше для полноты и для случая, когда filename
и size
меняют типы.
Также обратите внимание, что если filename
является строкой длины k
, тогда вам потребуется (k + 1)
байтов для этого из-за завершения 0
(так n == k + 1
выше).
Если предположить, вы хотите, чтобы размер
сохранял длину соответствующего имени файла
? В этом случае size
не должно быть char *
, а size_t
. Но поскольку я не знаю, как вы планируете использовать имя файла
и размер
, я не уверен.
Обязательно проверьте возвращаемое значение malloc ()
. В случае ошибки возвращается NULL
. Я пропустил проверку в приведенном выше коде для простоты.
Ваш пост тоже был помечен тегом C ++, поэтому, если вы хотите использовать C ++, есть и решение C ++.