LINUX.ORG.RU

[СИ] Коварный malloc.

 


0

1

[СИ] Коварный malloc.

Язык СИ
ОС UNIX

По совету анонимуса и других людей осваиваю malloc.

Ниже приведена небольшая тестовая программа. Смысл
ее в том, что в функции init_test(); выделяется
память malloc-ом, там же она первично инициируется
пробным текстом, указатель на эту память при
возврате из функции передается через аргумент главной
программе (main), и далее эта память используется
в главной программе.

Как я понимаю, память выделяется в статической памяти,
а не в стеке. И, стало быть, должна быть доступна и
при возврате в main. Выдача программы, как будто,
подтверждает это:

k=init_test()=0
proba malloc(); proba malloc(); proba malloc();
proba malloc() main()

Но сомнения все-же остались. В этом и вопрос:
можно ли выделять память в функции, а потом
использовать ее вне функции?

Кто знает прошу ответить.


Ответ на: комментарий от mv

Идеально, если буфер в А выделяется автоматически, в виде массива, а не malloc'ом.

Что ж тут идеального? Или будете лишнюю память выделять, или потеряете возможность динамического расширения (realloc).

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

> потеряете возможность динамического расширения (realloc)

Это не каждый раз нужно. Часто в прогах можно заметить использование маллока по мелочам (выделение мелких блоков на короткое время), что можно улучшить способом, который предложил mv. Но это не универсальный способ, конечно.

const86 ★★★★★
()
Ответ на: комментарий от anonymous

> man std::auto_ptr<>

К вашему сведению в СИ нет ни классов, ни шаблонов. Да и auto_ptr здесь не очень подходит, т.к. он для других целей проектировался PS: в сабже был указан язык СИ.

другой anonymous

anonymous
()
Ответ на: комментарий от Eddy_Em

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

anonymous
()
Ответ на: комментарий от beastie

> и да, никогда не используй strcat/strcpy — они протухли и плохие, используй strncat/strncpy

strncpy как бы тоже протух и плох. Приведенный тобой код кривой именно по причине неправильного использования strncpy.

anonymous
()
Ответ на: комментарий от anonymous

Ну, просто надо внимательнее следить за всеми malloc'ами и после того, как объект становится ненужным, вызывать free. А вот в конце программы всякие free и не нужны вовсе, так же как и close.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от mv

Второе точно не официальная дырка. Второе, пока еще не везде есть systemtap, что бы считать это аллокатором ;)

catap ★★★★★
()
Ответ на: комментарий от Eddy_Em

> Ну, просто надо внимательнее следить за всеми malloc'ами и после того, как объект становится ненужным, вызывать free.

Легко говорить внимательнее надо быть, практика показывает что такие ошибки очень распространены. Или вы хотите сказать, что никогда не сталкивались с утечками в языке Си?

anonymous
()
Ответ на: комментарий от anonymous

Или вы хотите сказать, что никогда не сталкивались с утечками в языке Си?

Сталкивался, конечно, но эти проблемы бывают не чаще, чем простые «очепятки», которые выявить бывает иногда не так то и просто...

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

> эти проблемы бывают не чаще, чем простые «очепятки»

Скорее зависит от проекта: где-то реже, где-то чаще.

anonymous
()
Ответ на: комментарий от Eddy_Em

> Чтобы переполнить буфер посредством strncpy, надо очень сильно постараться :)

Учитывая, что функция не гарантирует завершения строки нулевым символом, сильно стараться совсем не придется.

anonymous
()
Ответ на: комментарий от Eddy_Em

Этого недостаточно, т.к. завершающий нуль в случае слишком длинной строки сам собой не появится.

anonymous
()

Послушай совета анонимуса и освой K&R.

anonymous
()
Ответ на: комментарий от nikitos

тем, что это фактически тот же malloc и в зависимости от libc это либо надстройка над sbrk, либо над mmap.

catap ★★★★★
()
Ответ на: комментарий от Jetty

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

catap ★★★★★
()
Ответ на: комментарий от anonymous

тут есть нюанс:

     strncpy() copies not more than len characters into dst, appending `\0'
     characters if src is less than len characters long, and not terminating
     dst if the length of src is greater than or equal to len.

т.ч. вопрос спорный. лично я предпочинтаю, если уж использовать strncat & co.:

memset(dest, 0, size);
strncat(dest, src, size - 1);

но в любом случае strlcat лучше:

     The strlcpy() function copies up to size - 1 characters from the NUL-
     terminated string src to dst, NUL-terminating the result.

     The strlcat() function appends the NUL-terminated string src to the end
     of dst.  It will append at most size - strlen(dst) - 1 bytes, NUL-
     terminating the result.
beastie ★★★★★
()
Ответ на: комментарий от beastie

> вопрос спорный

Чтобы не было проблем строку надо обязательно завершать нулем, а как вы ее будете занулять (memset'ом или иначе) это уже другой вопрос. Лично я предпочитаю dest[size-1] = '\0'.

если уж использовать strncat

Ваш пример с strncat считаю неудачным, т.к. в случае strncat третий параметр это сколько взять из src, а не сколько места в dest.

но в любом случае strlcat лучше

strl* лучше, но к сожалению не является частью стандартной библиотеки языка Си.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.