开发者

Can the following be made simpler / more efficient?

I'm trying to convert some code from a dynamic-typed language to C. Please bear with me as I have no practical experience yet with C.

I have a dispatcher function that decides how to convert it's input based on the value of the flag argument.

void output_dispatcher(char *str, int strlen, int flag) {
    char output[501];
    char *result;

    switch (flag) {
        /* No conversion */
        case 0:
            result = str;
            break;
        case 1:
            result = convert_type1(output, str, strlen);
            len = strlen(result);
            break;
        /* ... */
    }
    /* do something with result */
}

I currently have 5 different output converters and they all (even future ones) are guaranteed to only produce 300-500 characters. From my reading, it is preferable to use a heap variable than dynamically allocate space on the stack, if possible. The function declaration for one looks like:

static char * convert_type1(char *out, const char *in, int inlen);

I want to avoid the strlen in the dispatcher, since it is uncessary to recalculate the output size because the output converters know it when they construct the output. Also, since I'm passing in a pointer to the output variable, I shouldn't need to return the result pointer, right? So I modify it to the following, but get an 'in开发者_JS百科compatible type' compilation error.

void output_dispatcher(char *str, int strlen, int flag) {
    char output[501];

    switch (flag) {
        /* No conversion */
        case 0:
            output = str;  /* ERROR: incompatible type */
            break;
        case 1:
            strlen = convert_type1(output, str, strlen);
            break;
        /* ... */
    }
    /* do something with result */
}

Can this approach work, or is there a better way to go?


To avoid the recalculation your output converters would need to have a prototype like this:

static char * convert_type1(char *out, const char *in, int *len);

called thus:

result = convert_type1(output, str, &strlen);

Internally the output converter would need to read the contents of the pointer now containing the string length, and overwrite the contents of that pointer before returning.

On the issue of heap vs stack, indeed you need to use the heap since variables allocated on the stack will disappear as soon as the function ends.


The line:

output = str;

is giving you problems because, while arrays and pointers are similar, they're not the same.

"output" is an array, not a pointer.

str = output;

will work, because a char ptr is much like an array variable.

But the opposite does not because the "output" variable is not just the pointer to the array, but the array itself.

For example, if you had:

char output[501];
char output1[501];

and you did:

output1 = output;

This would be ok, and C would copy the contents of the output array in to the output1 array.

So, you're just a little confused about arrays and ptrs.


char output[501]; output = str; /* ERROR: incompatible type */

=>

strncpy(output, str, sizeof(output));

Note, you should check if 'output' is big enough to hold 'str'


The error in this case makes sense. output is a buffer that will hold come char data, while str is a pointer to some other area in memory. You don't want to assign the address of what str is pointing to output, right? If you want to go with this approach I think would just copy the data pointed to by str into output. Better yet just use str if no conversion is required.


C does not allow arrays to be modified by direct assignment - you must individually modify the array members. Thus, if you want to copy the string pointed to by str into the array output, you must use:

strcpy(output, str);

or perhaps

memcpy(output, str, strlen + 1);

(In both cases, after first checking that strlen < sizeof output).

Note that naming a local variable strlen, thus shadowing the standard function of that name, is going to more than a little confusing for someone who looks at your code later. I'd pick another name.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜