재미 있기 때문에 다른 리터럴의 주소를 기반으로 추측하려고 시도했습니다. 잠재적 리터럴의 주소를 다른 알려진 리터럴, 스택 주소 및 힙 주소와 비교하여 작동합니다. 잠재적 주소가 다른 주소보다 리터럴에 더 가깝다면 잠재적 주소가 리터럴이라고 가정합니다. 아마도 실제로는 신뢰할 수 없습니다. 다음은 단순한 버전입니다.
int is_literal_simplistic(char *s) {
char *literal = "literal";
char stack[] = "stack";
char *heap = malloc(1);
free(heap);
unsigned long literal_delta = labs(literal - s);
unsigned long stack_delta = labs(stack - s);
unsigned long heap_delta = labs(heap - s);
return (literal_delta < stack_delta && literal_delta < heap_delta);
}
여기에는 좀 더 간결한 버전이 나와 있습니다.아마 수 있습니다 간단 :
int is_literal(char *s) {
char *heap = malloc(1);
free(heap);
unsigned long literal_delta = labs("literal" - s);
unsigned long stack_delta = labs((char *)&s - s);
unsigned long heap_delta = labs(heap - s);
return (literal_delta < stack_delta && literal_delta < heap_delta);
}
전체 실행 가능한 테스트 : 비교하기 전에 서명되지 않은 long``에 캐스팅하여`SafeFree() '함수의 전체 휴대 성을 개선하기위한
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
//#define DEBUG
#ifdef DEBUG
void debug_literal(unsigned long literal,
unsigned long stack,
unsigned long heap,
unsigned long literal_delta,
unsigned long stack_delta,
unsigned long heap_delta) {
printf("literal(%lx) stack(%lx) heap(%lx)\n", literal, stack, heap);
printf("literal(%lu) stack(%lu) heap(%lu)\n", literal_delta, stack_delta, heap_delta);
int answer = (literal_delta < stack_delta && literal_delta < heap_delta);
printf("\t%s\n", answer ? "literal" : "other");
}
#else
void debug_literal(unsigned long literal,
unsigned long stack,
unsigned long heap,
unsigned long literal_delta,
unsigned long stack_delta,
unsigned long heap_delta) {
}
#endif
int is_literal_simplistic(char *s) {
char *literal = "literal";
char stack[] = "stack";
char *heap = malloc(1);
free(heap);
unsigned long literal_delta = labs(literal - s);
unsigned long stack_delta = labs(stack - s);
unsigned long heap_delta = labs(heap - s);
debug_literal((unsigned long)literal, (unsigned long)stack, (unsigned long)heap,
literal_delta, stack_delta, heap_delta);
return (literal_delta < stack_delta && literal_delta < heap_delta);
}
int is_literal(char *s) {
char *heap = malloc(1);
free(heap);
unsigned long literal_delta = labs("literal" - s);
unsigned long stack_delta = labs((char *)&s - s);
unsigned long heap_delta = labs(heap - s);
debug_literal(0,0,0, literal_delta, stack_delta, heap_delta);
return (literal_delta < stack_delta && literal_delta < heap_delta);
}
void test_literal_function(int(*liternal_fn)(char *)) {
char *literal = "literal_test";
char stack[] = "stack_test";
char *heap = malloc(40);
printf("\t%s\n", liternal_fn(literal) ? "literal" : "other");
printf("\t%s\n", liternal_fn(stack) ? "literal" : "other");
printf("\t%s\n", liternal_fn(heap) ? "literal" : "other");
printf("\n");
free(heap);
}
int main() {
test_literal_function(is_literal_simplistic);
test_literal_function(is_literal);
return 0;
}
+1 (비록 작동하지 않습니다). 'uint_ptr'유형은 약간 더 좋을 것입니다. –
[이 SO 스레드]를 확인할 수도 있습니다 (http://stackoverflow.com/questions/2322647/how-to-detect-the-passing-of-a-string-literal-to-a-function-in-c) –
고마워요, 0x69, 그 스레드에서 귀하의 답변을 참조하십시오, 그 setjmp, longjmp 가능한 유일한 방법입니다 (권장하지 않음). 나는 char * strcatex (char * stringOne, char * stringTwo); 함수를 char * strcatex (char * stringOne, int doFreeOne, char * stringTwo, int doFreeTwo);로 재 작성하기로 결정했다. if (doFreeOne) free (stringOne);'단계입니다. setjmp, longjmp가 어떻게 작동하는지 보여 주셔서 감사합니다. –