Как освободить () malloc () 'd структурированный правильно?

у меня есть структура 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, я хочу, создают приложение, которое получает список файлов двух данных дисков/папок и затем сравнивает их. Я думал (и все еще сделал), что самый легкий путь, когда я храню имена файлов, и их размер в структуре любят упомянутый выше. Таким образом, я должен выделить память динамично (я думаю это, что они называют ею) для имени файла и размера и трупа для структуры также.

7
задан In silico 8 September 2010 в 02:21
поделиться

8 ответов

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

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.

7
ответ дан 6 December 2019 в 19:36
поделиться

Как выделены строки в структуре? Если они статически присваиваются константам, то не освобождайте их так, и все, что нужно, - это бесплатно ; , освобождающих что-то, что не было MALLOC

Если строковые указатели установлены MALLOC () или CALLOC (), это правильно.

3
ответ дан 6 December 2019 в 19:36
поделиться

Для перезагрузки текущей страницы можно вызвать window.location.reload (true) . Он игнорирует все кэшированные элементы и извлекает новые копии страницы, css, изображений, JavaScript и т.д. с сервера. Это не очищает весь кэш, но приводит к очистке кэша для страницы, на которой вы находитесь.

Однако лучшей стратегией является версия пути или имени файла, как указано в различных других ответах. Кроме того, см. Revving Filenames: не используйте строку запросов по причинам, не использующим ? v = n в качестве схемы управления версиями.

-121--655928-

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

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 .

-121--3909768-

Замена цикла for в нижней части кода на free (primary); должна работать.

0
ответ дан 6 December 2019 в 19:36
поделиться

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 для уничтожения объектов.

2
ответ дан 6 December 2019 в 19:36
поделиться

Это потому, что вы явно не выделили память для имени файла и размера . Таким образом, попытка сделать 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
0
ответ дан 6 December 2019 в 19:36
поделиться

Вы не можете измерить весь массив, приводящий к освобождению памяти мусора. Используйте 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(...);
}

(вы не описываете, какое значение имена файла есть, поэтому я оставляю ... в том, чтобы вы заполнить).

0
ответ дан 6 December 2019 в 19:36
поделиться

Это исправляет вашу проблему в мемсете, которая вызвала у вас всевозможные проблемы.

memset( primary, 0, sizeof(struct data) * primarypcs );  

Короче говоря, вы оставили неинициализированную память в конце вашей "первичной" структуры.

0
ответ дан 6 December 2019 в 19:36
поделиться

Как уже говорили другие, в показанном вами фрагменте есть две явно неправильные вещи:

  1. Вы не делаете ' t выделить память для членов filename и size только что выделенных структур,
  2. Ваш вызов 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 ++.

1
ответ дан 6 December 2019 в 19:36
поделиться
Другие вопросы по тегам:

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