Question

I'm writing a function that reverses a cstring not in place but returns the reversed cstring. What exactly should the return type be?

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

const char* reverStr(const char *str)
{
    char revStr[strlen(str)];
    int i;
    for(i = strlen(str)-1; i >= 0; i--)
        revStr[strlen(str)-1-i] = str[i];
    printf("returned value should be %s\n", revStr);
    return revStr;
}

int main()
{
    char aStr[] = "hello";
    char aStr2[] = "goodbye";
    printf("%s %s", aStr, aStr2);
    char* tmp = reverStr(aStr);//tmp now has garbage
    printf("\n%s", tmp);
    printf(" %s", aStr);
    return 0;
}

Gives warning: function returns address of local variable [enabled by default]| warning: initialization discards 'const' qualifier from pointer target type [enabled by default]|

I tried changing char* tmp to char tmp[] but it wouldn't compile. It confuses me when I should use an array and when I should use a pointer.

Was it helpful?

Solution

revStr is an array and ceases to exist after reverStr function exits. For more please read:

Where is the memory allocated when I create this array? (C)

const char* reverStr(const char *str)
{
    char revStr[strlen(str)];

    return revStr;  /* Problem - revStr is a local variable trying to access this address from another function will be erroneous*/
}


const char* reverStr(const char *str)
{
    const char * revStr = str;

    return revStr;  //ok
}

A modifiable l-value cannot have an array type. An l-value is an expression which can come on the left side of an assignment. You use an array when you want to declare lots of variables of the same type and you can index it easily since its layout will be in a sense contiguous.

You use pointers when you want to keep changing the values of the address where you variable points to.

You can do this:

char * p = "test";
p = "new";

But you cannot do this:

    char p[] = "test";
    char *p1 ="test1";
    p = p1; //error

Because their (arrays and pointers) types are not the same and the array p is a non-modifiable l-value.

Here is your fixed code. I tried to make less modifications.

OTHER TIPS

char revStr[strlen(str)]; allocates a local variable(an array) and when you are out of the scope of the reverStr function, its memory is released, which will lead any further usage of its pointer to be UB(segfault in most cases).

A correct way is to allocate the string on the heap and return its pointer like this

char* x = (char*)malloc(strlen(str));
...
return x;

This requires user to be responsible to free the memory. Or you could pass another parameter to your function for the result string.

I think you should use malloc to allocate a new string.

const char* reverStr(const char *str)
{
    char *revStr;//using pointer 
    int i;

    revStr = (char*)malloc(strlen(str));//dynamic allocation
    for(i = strlen(str)-1; i >= 0; i--)
        revStr[strlen(str)-1-i] = str[i];
    printf("returned value should be %s\n", revStr);
    return revStr;
}

An array is a pointer point to the head of continuous memory.

for example:

int a[] = {1,2,3};

The address in memory maybe:

--1000

|1|

--1004

|2|

--1008

|3|

--1012

1000, 1004, and 1012 are the value of address in memory.

Thus, the value of array a should be 1000.

printf("%d",a);// Yes, you can do it and you may get the value of 1000.

Also, you can use the following code.

int a[] = {1,2,3};
int *b;
b= a;
printf("%d",b[1]);// you will get "2".

You can consider that pointer is a set and array is in the set.

Therefore, you can NOT do this;

int a[] = {1,2,3};
int c = 0;
int *b  = &c;

a = b;//error
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top