In C, will the letter string address always be larger than any highlighted string address?

I am trying to distinguish literal lines from selected lines, so I am not accidentally trying to free () literal lines, which will cause segfault.

The reason I can try to free () literal strings is the strcat () shell, which can be inlined this way: strcatex("My name ", strcatex("is ", strMyName));

Whatever the reason, consider:

void* mallocex(int intBytes) 
{
    void* newPtr;

    newPtr = malloc(intBytes);

    if(newPtr == 0)
        return 0;
    else if(newPtr > maxPointer)
        maxPointer = newPtr;

    return newPtr;
}

and

int SafeFree(void **ptr)
{
    if((unsigned long) ptr > (unsigned long) maxPointer) 
        return 0;
    else
        free(*ptr);

    return 1;
}

usage example:

char *newString;
newString = (char*) mallocex(12);

strcpy(newString, "Example one");

SafeFree(&newString);
SafeFree("Example two");

Will it always work, no matter how big my pile is?

+3
source share
4 answers

, .
- , , , , .

+5

"", . , ( ). , ( malloc ), , - , . , .

+1

, , , , . , MacOS ( ):

#include <stdio.h>
#include <stdlib.h>

void pr_addr(const char *name, void *addr) {
    printf("%s: %p\n", name, addr);
}

int main(void) {
    pr_addr("literal", "literal");
    pr_addr("heap", malloc(10));
    return 0;
}
$ cc -o foo -W -Wall -O foo.c
$ ./foo
literal: 0x1ff1
heap: 0x100160

, rodata malloc, , .

, - , . p < q . , p q () , , . , p < q p > q p != q.

0

For pleasure, I wrote an attempt that tries to guess based on the addresses of other literals. It works by comparing the address of a potential literal with another known literal, the stack address and the heap address. If the potential address is closer to the literal than the others, it assumes that the potential address is a literal. In practice, this is probably unreliable. Here is a simplified version:

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);
}

here is a shorter version. Perhaps this will be easier:

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);
}

Full test:

#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;
}
0
source

All Articles