I understand that there are better implementations of this reverse string function, I even have made one better than this, but I just want to know why this isn't working.
I have _strlen(char *)
function that returns the length of a string.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
void rev_string(char *s)
{
int length = _strlen(s);
char *clone = s;
char *tmp = malloc(length * sizeof(char));
tmp += length;
while (*clone)
{
*tmp = *clone;
tmp--;
clone++;
}
tmp += 1;
//so if you print this and check it you can see the reversing was successful
//but I couldnt assign it back to the main string;
printf("TMP-->%s,s-->%s\n",tmp,s);
//I have debugged the problem to be in the next while loop
while (*tmp)
{
*s = *tmp;
tmp ++;
s++;
}
}
int main(void)
{
char *str;
str = "five";
rev_string(str);
printf("done");
printf("%s\n",str);
return (0);
}
I am trying to understand pointers in-depth and I don't really know much about them at this point so I really appreciate any answer.
Comment of @user3121023 completely correct.
but even if you do s = tmp that will not work because s it's just a copy. Althoug your code can work if will pass **s
void rev_string(char **s)
int length = _strlen(*s);
Replace whole last loop with *s = tmp
This will work as you expected. But never do this in real programs, it's bad solution.
According to the documentation of string literal :
String literals are not modifiable (and in fact may be placed in read-only memory such as .rodata). If a program attempts to modify the static array formed by a string literal, the behavior is undefined.
Example:
char* p = "Hello";
p[1] = 'M'; // Undefined behavior
char a[] = "Hello";
a[1] = 'M'; // OK: a is not a string literal
So, this
char *str = "five";
needs to be
char str[] = "five";
to be modifiable.
This statement
tmp += length;
makes tmp
to point to the memory one element after the allocated array.
And, accessing it first time with
*tmp = *clone;
is out-of-bounds access which is Undefined Behavior .
You can verify this with valgrind .
You need to allocate one extra character to accommodate the null-character so the length would be:
const size_t length = strlen(s) + 1;
and, the allocation would be:
char* tmp = malloc(length * sizeof(*tmp));
// ^^^^^^^^^^^^
// sizeof to variable idiom
The allocated memory needs to be freed after use to avoid the memory leak.
Here's the working example ( live ):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void rev_string(char *s)
{
const size_t length = strlen(s) + 1;
char *clone = s;
char *tmp = malloc(length * sizeof(*tmp));
char *p = tmp + length - 1;
*p = '\0';
p--;
while (*clone)
{
*p = *clone;
p--;
clone++;
}
++p;
printf("TMP: %s, s: %s\n", p, s);
while (*p)
{
*s = *p;
p++;
s++;
}
free(tmp);
}
int main()
{
char str[] = "five";
rev_string(str);
printf("%s\n",str);
return (0);
}
Output:
TMP: evif, s: five
evif
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.