StackOverflow
[C] C언어에서, 메모리 포인터를 해제하기 전에 캐스팅해야 하는 이유?
StanleyKou
2015. 12. 4. 09:49
http://stackoverflow.com/questions/34019977/in-c-why-do-some-people-cast-the-pointer-before-freeing-it
Q: C언어에서, 어떤 사람들은 메모리 포인터를 해제하기 전에 캐스팅을 합니다. 왜 그런가요?
메모리를 해제할 때 free를 이용하게 되는데, 각 포인터는 자신의 타입을 가지고 있습니다. 그런데 왜 캐스팅을 해줘야 하죠? 이런 일을 하는 뭔가 기술적인 이유가 있나요?
(질문자: Dr. Person Person II)
A : const로 할당된 dynamic 메모리를 해제할 때, 컴파일러가 에러를 발생시키는 경우가 있습니다. 이 경우 캐스팅을 해주면 컴파일 에러를 막을 수 있습니다. (답변자:Manos Nikolaidis)
-> 근데 왜 const 변수를 dynamic으로 할당하죠? 처음 설정된 값이 영원히 변하지 않을테니, 그렇게하지 않아도 될텐데요 (Nils_M)
-> 이건 그냥 한가지 예일 뿐입니다. (Manos Nikolaidis)
A : 비표준 C에서는 void*가 없었기 때문에, char*를 이용해서 메모리를 일단 할당한 뒤 다른 타입으로 강제로 캐스팅해서 썼습니다. C의 첫번째 표준안에서 메모리 할당이나 해제의 기본이 char*가 아닌, void* 로 정해졌고, 오늘날까지 이어지고 있습니다. 최신 컴파일러를 이용한다면, 이런 코드는 가독성을 떨어뜨릴 뿐입니다. (답변자 Lundin)
| I'm working on an old code base and pretty much every invocation of free() uses a cast on its argument. For example, free((float *)velocity);
free((float *)acceleration);
free((char *)label);
where each pointer is of the corresponding (and matching) type. I see no point in doing this at all. It's very old code, so I'm left wondering if it's a K&R thing. If so, I actually wish to support the old compilers that may have required this, so I don't want to remove them. Is there a technical reason to use these casts? I don't even see much of a pragmatic reason to use them. What's the point of reminding ourselves of the data type right before freeing it? EDIT: This question is not a duplicate of the other question. The other question is a special case of this question, which I think is obvious if the close voters would read all the answers. |
| |
| |
| Casting may be required to resolve compiler warnings if the pointers are const . Here is an example of code that causes a warning without casting the argument of free: const float* velocity = malloc(2*sizeof(float));
free(velocity);
And the compiler (gcc 4.8.3) says: main.c: In function ‘main’:
main.c:9:5: warning: passing argument 1 of ‘free’ discards ‘const’ qualifier from pointer target type [enabled by default]
free(velocity);
^
In file included from main.c:2:0:
/usr/include/stdlib.h:482:13: note: expected ‘void *’ but argument is of type ‘const float *’
extern void free (void *__ptr) __THROW;
If you use free((float*) velocity); the compiler stops complaining. |
| |
| Pre-standard C had no void* but only char* , so you had to cast all parameters passed. If you come across ancient C code, you might therefore find such casts. Similar question with references. When the first C standard was released, the prototypes for malloc and free changed from having char* to the void* that they still have today. And of course in standard C, such casts are superfluous and just harm readability. |
| |
| Here's an example where free would fail without a cast: volatile int* p = (volatile int*)malloc(5 * sizeof(int));
free(p); // fail: warning C4090: 'function' : different 'volatile' qualifiers
free((int*)p); // success :)
free((void*)p); // success :)
In C you can get a warning (got one in VS2012). In C++ you'll get an error. Rare cases aside, the casting just bloats the code... Edit: I casted to void* not int* to demo the failure. It will work the same as int* will be converted to void* implicitly. Added int* code. |
| |
void*
in pre-standard C, but onlychar*
. So if your archaeological findings reveal code casting the parameter to free(), I believe it must either be from that time period, or written by a creature from that time. I can't find any source for this though, so I'll refrain from answering. – Lundin 2 days ago