0
votes

I'm recently writing a function to reverse a string input. For example, input = "hello", then output = "olleh" I got a question, when I return the address of char*, it looks fine, but why I cannot print the string of that pointer ?

many thanks at first and here is my code :

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

char* reverseString(char*);

int main(void)
{
    char* s = "hello";
    char* out;

    out = reverseString(s);

    printf("%p %s\n", out, out);
    return 0;
}

char* reverseString(char* s)
{
    int i;
    int size;
    char* reverse;

    size = sizeof(s);
    char reversechar[size];

    for (i = 1; i < size + 1; i++)
        reversechar[i - 1] = s[size - i];

    reverse = reversechar;
    //printf("%p\n",reverse);
    return reverse;
}

result : 0x7fff40db7300 @@

3
reverse points to memory on the stack, being valid only inside reverseString. The moment reverseString returned this memory had already been dealloctated. - alk
Also this size = sizeof(s); does not do what you'd expect. It returns the size of s. s is a pointer, and a pointers size is either 4 or 8 depending on the platform. Use strlen() instead. - alk
Consider pushing up the compiler's warning level to the maximum, then fix the code until no more warnings are issued. Then compile with symbols and run the code inside a debugger tracing through it step by step, inspecting all relevant variables to learn what is really going on. If then you still face issues come back here. - alk
This isn't valid C++; please don't tag C questions as C++. - Alan Stokes

3 Answers

2
votes

Don't allocate reversechar inside the function. It will go out of scope when the function returns (i.e. it is not valid to access it anymore). Instead allocate it in main and pass a pointer to the function. Something like:

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

 void reverseString(char* dst, char* s)
 {
    int i;
    int size;

    size = strlen(s);

    for(i = 0; i < size; i++)
      dst[i] = s[size-1-i];

    // Terminate the string
    dst[size] = 0;

 }

 int main(void)
 {
    char* s = "hello";
    char out[strlen(s)+1];

    reverseString(out, s);

    printf("%p %s\n",out,out);

    return 0;
 }

Compare this to functions like strcpy and memcpy. They don't allocate memory for you. They require you to give both the source and the destination pointer.

1
votes

Several things in your code:

-you try to return a pointer to an array that has automatic storage duration which invokes Undefined Behavior if you use it.

-when trying to print a pointer,cast (void *) to it.

-Use strlen() function to obtain the length of the string,not sizeof operator`.

You should allocate an array dynamically using malloc() inside your function,and free it later when finished.

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

char* reverseString(char*);

int main(void)
{
    char* s = "hello";
    char* out;

    out = reverseString(s);

    printf("%p %s\n", (void *)out, out);

    free(out);
    return 0;
}

char* reverseString(char* s)
{
    char *reverse;
    size_t i, size;

    size = strlen(s);
    char *reversechar = malloc(size + 1);

    for (i = 1; i < size + 1; i++)
        reversechar[i - 1] = s[size - i];

    reverse = reversechar;
    //printf("%p\n",reverse);
    return reverse;
}
0
votes
#include <string.h> // for strlen

char* reverseString(char* s)
{
    int i;
    int size;
    char* reverse;

    // size = sizeof(s);
    // char reversechar[size];
    //  ↓
    size = strlen(s);
    char* reversechar = calloc(size + 1, sizeof(char)); // memory allocation and zero-initialization

    for (i = 1; i < size + 1; i++)
        reversechar[i - 1] = s[size - i];

    reverse = reversechar;
    //printf("%p\n",reverse);
    return reverse; // it is necessary that return value is freed by the caller
}
1. size of string

char* s = "hello world";

Address(64bit)    h  e  l  l  o     w  o  r  l  d  /0
0x00007FFF40DB7300:68 65 6c 6c 6f 20 77 6f 72 6c 64 00

  s・・・0x00007FFF40DB7300
  sizeof(s)・・・8  (64bit)
  strlen(s)・・・11 (string length)

In the case of 「char s[] = "hello world";」

  sizeof(s)・・・12 (allocation size)


2. initialization

char buf[5];
0x0000xxxxx22DD100:CD CD CD CD CD (5bytes)

char* buf = malloc(5);
0x0000xxxxx8212A00:CD CD CD CD CD (5bytes)

char* buf = calloc(5 * sizeof(char));
0x0000xxxxx55A6600:00 00 00 00 00 (5bytes)(zero-values)