1
\$\begingroup\$

This is part of the project I started just now. It is a function that returns the offset address of a first occurrence of a string match into a given range of memory blocks.

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

typedef struct
{
    unsigned long offset;
    unsigned long terminal;
} Range;

unsigned long memgr_locate (char string[], Range iRange)
{
    unsigned char * ptr = (char*)iRange.offset;
    unsigned long i;
    unsigned long c = 0;

    for(i = iRange.offset; i <= iRange.terminal; i += 1)
    {
        ptr = (char*)i;

        (*ptr == string[c]) ? (c++) : (c=0);
        if(string[c + strlen(string) - 1] == '\0')
            break;
    }
    return i;
}


int main(void)
{
    char * test = malloc(100);
    strcpy(test, "Looking for Sample string directly in memory..");

    Range iRange = {test, test + 50};

    printf("%s", (char*)memgr_locate("Sample", iRange));


    return 0;
}

Test result:

Sample string directly in memory..

Note that the string searcher function is constructed like so to return the closest result.

Example:

If we look for the string "s" it will return the offset byte of the first word from the memory range that starts with "s". If we look for "str" it will return the first word starting with "str". This behavior IS intended.

\$\endgroup\$
2
\$\begingroup\$

The compiler gives me several warnings:

st.c: In function 'main':
st.c:34:5: warning: initialization makes integer from pointer without a cast [enabled by default]
     Range iRange = {test, test + 50};
     ^
st.c:34:5: warning: (near initialization for 'iRange.offset') [enabled by default]
st.c:34:5: warning: initialization makes integer from pointer without a cast [enabled by default]
st.c:34:5: warning: (near initialization for 'iRange.terminal') [enabled by default]

Indeed, your program has many casts from unsigned long to char *. You shouldn't ignore warnings, and strive to eliminate them all.


There seem to be several problems with this piece:

    if(string[c + strlen(string) - 1] == '\0')
        break;

First of all, calling strlen in every iteration of the loop is wasteful, it would be better to call it once before and cache the length in a variable.

Secondly, I doubt this is intended behavior. This statement will cause the loop to exit when c = 1. So if your test string is "Looking for S Sample string" and the string parameter is "Sample", then the output will be "S Sample string" instead of "Sample string". So this looks like a bug. Perhaps you're looking for something like if (c == len) { i -= c - 1; break; } (where len is strlen(string), cached before the loop).


The variable names don't seem great. Why not simply range instead of iRange? How about target instead of string? Why use Range at all instead of two variables?

\$\endgroup\$
  • \$\begingroup\$ Ahh yes thats what I had in mind if (c == len) { i -= c - 1; break; }. Thanks for the reminder for the strlen call, I always seem to forget it.. I firstly intended to not use other functions at all but.. \$\endgroup\$ – Edenia Jan 17 '15 at 15:37
  • \$\begingroup\$ I type-casted to (unsigned long) in order to eliminate the warnings and changed the names. \$\endgroup\$ – Edenia Jan 17 '15 at 15:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.