C에서 항상 포인터를 해제할 수 없음
A을(를) 어떻게 해제할 수 있는가?const char*
? 다음을 사용하여 새 메모리를 할당했다.malloc
, 그리고 내가 그것을 해제하려고 할 때 나는 항상 "호환할 수 없는 포인터 유형"이라는 오류를 받는다.
이것을 일으키는 코드는 다음과 같다.
char* name="Arnold";
const char* str=(const char*)malloc(strlen(name)+1);
free(str); // error here
여러 사람이 정답을 올렸는데 웬일인지 자꾸 삭제한다.일정하지 않은 포인터로 던져야 한다.free
에 걸리다void*
, a가 아니다.const void*
:
free((char*)str);
코드가 바뀌었어.
다음 내용:
char* name="Arnold";
const char* str=(const char*)malloc(strlen(name)+1);
다음과 같이 표시되어야 함:
const char* name="Arnold";
char* str=(char*)malloc(strlen(name)+1);
그const
저장소 유형은 컴파일러에게 일단 할당된 메모리 블록(일시적으로 또는 정적으로)을 수정할 의도가 없음을 알려준다.기억을 자유롭게 하는 것은 그것을 수정하는 것이다.참고로, 말로크()의 반환가치를 주조할 필요는 없지만, 그것은 하나의 차이에 불과하다.
(당신이 하고 있는 것을, 의 길이를 기준으로, 동적으로 메모리를 할당하는 것은 거의 쓸모가 없다.name
( ) 그리고 컴파일러에게 당신은 그것을 사용할 의사가 없다고 말한다.참고: 어떤 것을 그것에 쓰고 나중에 자유롭게 하는 것을 의미하면서.
다른 스토리지 유형에 캐스팅한다고 해서 스토리지 유형을 되돌린 사실이 해결되는 것은 아니다 :) 경고가 사라지기만 할 뿐, 이 경고가 사라진다.
코드가 반전된 경우(필요한 경우),free()
당신이 실제로 당신이 할당한 메모리를 수정할 수 있기 때문에 예상대로 작동할 것이다.
만록의 포인터를 던져도 아무런 목적이 없다.항상 포인터를 사용하는 기능은 전달된 메모리를 자유롭게 할 책임이 없어야 한다.
몇몇 답변은 단순히 에 의존하는 것을 시사했다.char*
그러나 엘페스카도가 위에 썼듯이
캐스팅
const
비-비-비-const
코드 냄새의 증상이다.
-Wcast-qual
gcc로, 매우 유용하다고 생각한다.만약 당신이 정말로 a를 풀어줄 유효한 케이스가 있다면const
포인터(많은 사람이 여기에 작성한 내용에 따라, nlstd에서 지적한 바와 같이 유효한 사례가 있다)와 같은 목적으로 매크로를 정의할 수 있다.
#define free_const(x) free((void*)(long)(x))
이것은 적어도 gcc에게는 효과가 있다.이중 캐스팅이 논리를 만든다.-Wcast-qual
이것을 "완전 항상성"으로 감지하지 못한다.말할 필요도 없이, 이 매크로는 주의 깊게 사용되어야 한다.사실 그것은 동일한 기능에 할당된 포인터에만 사용되어야 한다.
당신이 자유롭게 하고 싶은 케이스가 있다.const*
그러나 동일한 기능으로 할당/할당하지 않으면 이 작업을 수행하지 마십시오.그렇지 않으면 너는 물건을 망가뜨릴 것 같다.실제 예는 아래 코드를 참조하십시오.나는 사용한다const
함수의 선언에서 내가 변수의 내용을 변경하지 않음을 표시한다.그러나 그것은 자유로워질 필요가 있는 낮은 분류의 복제품(지연)으로 재지정된다.
char* tolowerstring(const char *to_lower)
{
char* workstring = strdup(to_lower);
for(;workstring != '\0'; workstring++)
*workstring = tolower(workstring);
return workstring;
}
int extension_checker(const char* extension, const char* to_check)
{
char* tail = tolowerstring(to_check);
extension = tolowerstring(extension);
while ( (tail = strstr( tail+1, extension)) ) { /* The +1 prevents infinite loop on multiple matches */
if ( (*extension != '.' ) && ( tail[-1] != '.'))
continue;
if ( tail[strlen(extension)] == '\0') {
free(tail);
free( (char*) extension);
return 1;
}
}
free(tail);
free( (char *) extension);
return 0;
}
내가 틀릴 수도 있지만 문제는 에 있다고 생각한다.const
일정하지 다음과 같이 일정하지 않은 곳에 포인터를 놓으십시오.
free((char *) p);
왜냐하면const
당신은 다음과 같이 말한다.이 포인터가 가리키는 데이터를 변경하지 마십시오.
순수한 C에 대해 이야기하고 메모리 할당을 완전히 제어하는 경우, 다음과 같은 트릭을 사용하여 컴파일러에서 경고를 제공하지 않는 (const char *) ~ (char *)를 캐스팅(const char *)할 수 있다.
const char *const_str = (const char *)malloc(...);
char *str = NULL;
union {
char *mutable_field_p;
const char *const_field_p;
} u;
u.const_field_p = const_str;
str = u.mutable_field_p;
이제 당신은 자유(str)를 사용할 수 있다; 기억을 자유롭게 하기 위해.
그러나 이것은 말로 표현할 수 없을 정도로 사악하며 엄격히 통제된 환경에서만 사용되어야 한다는 점에 주의하십시오(예: 문자열을 할당하고 자유화하지만 사용자가 수정하는 것을 허용하지 않는 라이브러리). 그렇지 않으면 누군가가 자유 기능에 "STRING" 시간을 제공할 때 프로그램이 중단될 것이다.
(추악한 해킹이 없으면) 그 내용을 수정할 수 없기 때문에, 포인터로 하여금 항상성을 유지하도록 하는 것은 말이 안 된다.
그러나 gcc는 다음과 같은 경고만 한다.
//
// const.c
//
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
const char *p = malloc(100);
free(p);
return 0;
}
$ gcc -Wall const.c -o const
const.c: In function ‘main’:
const.c:8: warning: passing argument 1 of ‘free’ discards qualifiers from pointer target type
$
어떤 컴파일러를 사용하십니까?
자유 함수의 서명을 살펴보면 자유 함수는 항상 void* ptr을 인수로서 사용하므로 적절한 유형(예: free(void *) str)으로 주조할 필요가 있다; 자유 함수는 모든 구성 요소를 직접 할당 해제할 수 없으므로 비구조 유형으로 주조할 필요가 있다.
당신은 자유롭게 할 수 없다.const char *
그렇기 때문이다.const
하십시오.malloc
일정하지 않은 포인터 변수에서 전달 가능free
합격할 수 있다.char *
세계대항전에 const char *
그러나 반대되는 주장들이 항상 진실인 것은 아니다.
void foo (const char *x);
char *ptr = malloc (...);
foo (ptr);
free (ptr);
내 생각에 진짜 답은 자유는 자유가 있어야 한다는 것이다.const
포인터 인수 및NULL
다음과 같이 정의되어야 한다.const
포人터 인 것 이것은 기준의 버그인 것 같다.자유화 aconst
포인터는 다음과 같이 구현해야 한다.
free(p);
p = NULL;
컴파일러가 어떻게 이런 경우에 잘못된 코드를 만들 수 있는지 모르겠다.const
포인터p
더 이상 접근할 수 없기 때문에, 그것이 가리키는 물체가const
다른 어떤 것이든 유효하다.그것들const
기록부나 다른 곳에 더러운 복사본이 있을 수 없도록.다음과 같이 설정하는 것이 유효하다.const
다른 그 가 대인기라는 .NULL
이전 값은 더 이상 액세스할 수 없기 때문에 중요하지 않다.
비구체적인 것에 포인터를 던져도 자유의지의 결과는 이행에 달려 있다고 생각한다.보통 constitution은 수정하고 싶지 않은 변수에 맞게 설계되었어!!
참조URL: https://stackoverflow.com/questions/2819535/unable-to-free-const-pointers-in-c
'Programing' 카테고리의 다른 글
vue/vuex 반응도 제한 (0) | 2022.04.21 |
---|---|
gwt 컴파일러의 속도를 높이려면 어떻게 해야 하는가? (0) | 2022.04.21 |
왜 1,000,000,000을 1000*1000*1000으로 C에 쓰는가? (0) | 2022.04.21 |
Vue 사용법.웹 팩을 사용하지 않고 끌 수 있는 CDN? (0) | 2022.04.21 |
Java를 MySQL 데이터베이스에 연결 (0) | 2022.04.21 |