-3

Если у меня есть указатель на функцию, и я знаю, какой размер это, было бы лучше использовать malloc при инициализации указателя? Например, , если у меня есть функция, было бы лучше сделать этоЛучше ли инициализировать переменную с помощью malloc?

int * func(int size){ 
    int * ptr = (int *) malloc(size); 
    //some code 
    return ptr; 
} 

или это

int * func(int size){ 
    int * ptr; 
    ptr = (int *) malloc(size); 
    //some code 
    return ptr; 
} 
+2

Я бы использовал 'int * ptr = malloc (sizeof * ptr * size);' Интересно, учитывает ли '' size вашего '' sizeof (int) '. – chux

+3

Пожалуйста, определите термин «лучше». –

+0

Второй не инициализатор, а (начальное) назначение. – Olaf

ответ

-1

Они в основном то же самое. Я хочу просто дать вам совет, всегда инициализировать указатель с помощью NULL (вы не во втором фрагменте). Кроме того, не забудьте освободить() память для динамически назначенной переменной внутри функции.

+0

Он хочет инициализировать указатель с результатом 'malloc'. добавив дополнительный «NULL», прежде чем это будет не только избыточным, но может скрыть предупреждение компилятора о случайном использовании переменной и затруднит оптимизацию компилятора (например, оптимизатор может использовать пространство для этого указателя с другой переменной, которая не используется после malloc). –

+0

@ M.M Меня учили всегда инициализировать переменные. Указатель - это переменные, поэтому я инициализирую их с помощью NULL. Мне кажется, что инициализация переменных является хорошей практикой по многим причинам. –

+0

Мне кажется плохой практикой для меня по причинам, которые я упоминал. В любом случае проблему следует избегать, не объявляя эту переменную, пока вы не будете готовы ее инициализировать. –

1

«Насколько это более эффективно?»

Небольшая или незначительная разница в эффективности во время работы. @Jens Gustedt

Лучше ли инициализировать переменную с помощью malloc?

Да, лучше инициализировать переменную чем-то, а не ничего. Ни фрагменты кода OP не подходят для других целей. Нет необходимости выдавать результат malloc(). size_t - лучший аргумент, чем int. size_t - это правильный размер, чтобы держать размер всех массивов и результат sizeof().

int *func(int size) { 
    int *ptr = malloc(size); 
    //some code 
    return ptr; 
} 

Пока неясно, если size относится к числу элементов в массиве int или предполагаемого размера одного int. Рекомендовать:

int *func(size_t array_n) { 
    int *ptr = malloc(sizeof *ptr * array_n); 
    //some code 
    return ptr; 
} 
2

Первая форма лучше в том смысле, что ваш код более безопасен; вы знаете, что ptr будет либо содержать действительное значение адреса, либо NULL перед его первым использованием.

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

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

Вы должны всегда инициализировать переменные-указатели на время объявления и ИМО следует отложить их заявление пока вы на самом деле необходимость им.IOW, вместо того, чтобы писать что-то вроде этого:

void foo(void) 
{ 
    int *ptr = NULL; 
    /** 
    * several dozen lines of code 
    */ 
    ptr = malloc(sizeof *ptr * number_of_elements); 
    /** 
    * do stuff with ptr 
    */ 
} 

это лучше написать так:

void foo(void) 
{ 
    /** 
    * several dozen lines of code 
    */ 
    int *ptr = malloc(sizeof *ptr * number_of_elements); 
    /** 
    * do stuff with ptr 
    */ 
} 

Конечно, это возможно только с C99 на; если вы используете компилятор C89 или более ранний, все объявления должны перед любыми исполняемыми операциями в блоке.

Обычные нит:

  • Не отвергни результат malloc; с C89 это не нужно, и в C89 компиляторы могут маскировать ошибку. Это все еще требуется для C++, но если вы пишете C++, вы все равно не должны использовать malloc. Если вы пишете код, который должен быть создан как C и C++, скройте свой код выделения памяти за интерфейсом и реализуйте его по-разному для каждого. Я не шучу.
  • Использование sizeof *ptr вместо sizeof (type) в malloc вызова, такие как
    int *ptr = malloc(sizeof *ptr * number_of_elements);
    Это уменьшит головную боль технического обслуживания, если вы когда-либо изменить тип ptr (скажем, от int * к unsigned * или long *).
+0

В C89 вы обычно можете достичь того же цели, запустив блок с объявлением. Если это делает ваш код уродливым, подумайте о том, что у вас нет таких больших функций. –

+0

При написании кода, который должен быть создан для C и C++, другим способом является размещение кода выделения в файле C (C++ позволяет связать объекты C) –

Смежные вопросы