Reverse char string with pointers - c++

I need reverse my char string only with pointers. How can I do this? My code:
// this cannot be modified !!!
char s[10] = "abcde";
char *pS;
// my code
pS = new char;
int count = 5;
for (int i = 0; i < 10; i++)
{
if (s[i] != '\0') // not null
{
pS[count - 1] = s[i];
count--;
}
}
cout << "Reversed = " << pS;
Sometimes if works fine, I see only 5 chars, they are reversed. But sometimes I see some extra chars (looks like temp symbols). Where I miss something? Thank you!

your char array "s" contains 10 chars, but you only initialize the first 6 chars of that array with "abcde" and the \0 terminator.
When you loop over the complete array, you access not initialized chars.
I also see, that you try to write to memory, which you didn't allocate.
You only allocate memory for 1 char for you "pS" pointer, but you try to access it's memory like it is an array of chars in your for-loop.
Instead of using hardcoded:
int count = 5;
you also could use the string function strlen() to determine the length of the c-string.
Edited (untested code):
char s[10] = "abcde";
char pS[10];
for (int i = 0; i < strlen(s); i++)
{
if (s[i] == '\0') // not null
{
// stop loop, as soon as you reach the end of the original string
break;
}
pS[strlen(s) - 1 - i];
}
// now add the termination char \0 to your pS array
pS[strlen(s)] = '\0';
cout << "Reversed = " << pS;

Just giving you the hint how to reverse the string using pointers:
Take two pointers front and rear where front is pointing to first char of string and rear is pointing to last char of string.
Check if front is less than rear
If yes, swap the value of first and last character. If no , just print the string.
Increment front pointer and decrement rear pointer
Repeat from step 2.

After reading another book I fully understand pointers and how to correctly allocate memory. Here is my final code which correctly reverse array of char string (I don't need universal code, just working example + without std methods for reversing):
// not edited part - based on exercise (I mean I cannot change pS to char[5] etc.
char s[10] = "abcde";
char *pS;
pS = new char[strlen(s) + 1]; // allocate correct memory size based on string size
cout << "Size is " << sizeof(pS) << endl; // just for testing
int count = strlen(s); // for iteration
pS[count] = '\0'; // last symbol must be '\o' (thanks to Mr.Yellow)
for (int i = 0; i < 10; i++) // 10 because array of char still has 10 elements
{
if (s[i] != '\0') // looks like "not garbage memory"
{
count--;
pS[count] = s[i]; // set correct value
}
}
cout << "Reversed = " << pS << endl;
Thank you to all who helps me!

Related

copying a char array with and without a pointer

can someone help me here. I am experimenting on copying an array of characters using char array (in the first case) and using a pointer(in the second case) I understand why I need a temp[i]='\0' immediately after the while loop in the first case but I dont understand why I dont need it after the while loop in second case.
1st case:
char source[50] = "Hello World";
char temp[50];
int i = 0;
while (source[i] != '\0')
{
temp[i] = source[i];
i++;
}
temp[i]='\0';
cout << temp;
2nd Case:
char source[50] = "Hello World";
char *temp=source;
int i = 0;
while (source[i] != '\0')
{
temp[i] = source[i];
i++;
}
cout << temp;
I understand why I need a temp[i]='\0' immediately after the while loop in the first case
Right, because you stopped the loop just before copying the '\0', so you have to do so artificially at the end.
I dont understand why I dont need it after the while loop in second case.
Because temp is not a new array — it's just a pointer to the elements of the old one. Every single assignment in that loop is like x = x: you're just overwriting an array with itself.
You don't need to add a '\0' because the source array is the destination array, so it's already there.
In logical terms, the code in the second case achieves nothing.

Char* Array Memory Leak

I am having issues de-allocating memory that I used in my char* array. In my code snippet below, I am creating a char* array named input that holds pointers to single words at a time followed by a pointerNULL at the end of the array. This is the only time (I believe) I allocate memory in my code.
char* input[999];
//exec commands
for(unsigned int i = 0; i < commands.size(); i++)
{
string current = "";
string word = "";
int k = 0;
for(unsigned int j = 0; j < commands.at(i).size(); j++) //iterate through letters
{
current = commands.at(i);
//cout << "current: " << current << endl;
if(current[j] == ' ')
{
input[k] = new char[word.size() + 1];
strcpy(input[k], word.c_str());
k++;
word = "";
}
else
word += current[j]; //add letter
//cout << "word: " << word << endl;
}
input[k] = new char[word.size() + 1];
strcpy(input[k], word.c_str());
k++;
input[k] = new char[1]; //add the NULL char *
input[k] = NULL;
...
Later on, I attempt to de-allocate this memory with this snippet of code:
for(int z = 0; z < k; z++)
{
delete[] input[z];
}
I am iterating through my char* array and deleting the memory allocated at each index. Without using this snippet, valgrind informs me of memory leaks. Using this snippet, valgrind informs me of less memory leaks than before. I am still stuck with the issue of memory still being definitely lost.
I am unsure what I am missing to remove the rest of the allocated memory (or if the cause of the rest of the memory leaks is in fact somewhere else in my code). I appreciate any and all help, suggestions, and tips.
I think, your problem is in below case,
input[k] = new char[1]; //add the NULL char *
input[k] = NULL;
here, without free-ing input[k], you're assigning NULL to it. Thus, the previous input[k] is lost.
If you really want input[k] to hold NULL, (maybe as a sentinel value), you can simply do
input[k] = NULL;
No need to allocate memory separately.
You don't need to create a new char on where it says input[k] = new char[1]; //add the NULL char * Just leave the NULL assignment in and it should work fine.

C++ Copying an array of chars using char* (no string libraries)

I am writing a C++ function that is supposed to duplicate an array of chars by copying each element character-by-character into a new array. Ideally, if I make the statements
char* a = "test";
char* b = copyString(a);
then both a and b should contain the string "test." However, when I print the copied array b, I get "test" plus a series of nonsense characters that seem to be the pointer. I don't want those, but I can't figure out where I'm going wrong.
My current function is as follows:
char* copyString(char* s)
{
//Find the length of the array.
int n = stringLength(s);
//The stringLength function simply calculates the length of
//the char* array parameter.
//For each character that is not '\0', copy it into a new array.
char* duplicate = new char[n];
for (int j = 0; j < n; j++)
{
duplicate[j] = s[j];
//Optional print statement for debugging.
cout << duplicate[j] << endl;
}
//Return the new array.
return duplicate;
}
For the purposes of understanding certain aspects of C++, I cannot use string libraries, which is where other answers I have found have fallen short in this case. Any help with this problem is greatly appreciated.
EDIT: I though my stringLength function was fine - perhaps I was wrong.
int stringLength(char* s)
{
int n;
//Loop through each character in the array until the '\0' symbol is found. Calculate the length of the array.
for (int i = 0; s[i] != '\0'; i++)
{
n = i + 1;
}
//Optional print statement for debugging.
// cout << "The length of string " << s << " is " << n << " characters." << endl;
return n;
}
You need to copy the 0 too. That's what a C-style string is, a null-terminated character array.
Really, all you need to do is add one to the length:
int n = stringLength(s) + 1; // include the '\0'
And then everything else will account for itself - you'll allocate an array of sufficient size, and copy the '\0' in your loop too.

Transfer an array of char via pointer to another temp array pointer

I'm learning to use pointer to copy char array.
I have the following code in C++. What I'm trying to do is to transfer and array (set1) using pointer to another pointer array (temp).
But when I try to print out (temp), it is not the same as (set1).
Transfer an array via pointer to another temp array pointer.
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
char set1[] = "ABC";
char* p = &set1[0];
int tempSize = 0;
char* temp = new char[256];
for (int i = 0; i < 3; i++)
{
*temp = *p;
cout << *temp; // ABC
++temp;
++tempSize;
++p;
}
cout << "\n";
for (int i = 0; i < tempSize; i++)
{
cout << temp[i]; // Why ABC is not printed?
}
delete [] temp;
return 0;
}
// Why ABC is not printed?
Because your pointer is travelling in undefined behavior region:
char* temp = new char[256];
...
++temp; // gone !!
On top of that,
you are not terminating the string with \0 in the end (may not be needed in your code)
delete[]ing this corrupt pointer in the end.
Since you are writing for learning purpose, I would suggest simple fix to your code:
char* const temp = new char[256];
^^^^^ ensures `temp` is not modifiable
Now use temp[i] for traversing purpose.
It's because in the loop copying the array, you change temp. After the loop, it points to one beyond the copied data.
Also, you forget to terminate the new allocated array. You should add the character '\0' at the end.
The problem is this line:
++temp;
You are incrementing the pointer and then write to it. In the end temp[i]; does not point to the beginning of your string, but to the end.
The easiest way to do this is to remove the first for loop with:
for (int i = 0; i < 3; i++)
{
temp[i] = set1[i];
}
temp[4] = '\0'; // don't forget to close the string
C-style strings have a null terminator - "ABC" contains four characters. Also, I'm not at all sure that the delete call on temp is valid - you have been incrementing it since it was 'newed'.

Why is my Dynamic Array of Char's still returning uninitialized values?

For some weird reason, it keeps on creating uninitilized values when I pass in the length as 12, it creates an array of about 16 and stores the rest with crap that I don't want. Anyone know why this isn't working? It's for an assignment that's due tomorrow and this is my last problem... Any help would be appreciated thanks.
char * convertToUppercase (char* toUpSize, int length) {
std::cout << "ToUpsize: " << toUpSize << "\nLength: " << length << "\n";
char * upsized = new char[length];
for (int i = 0; toUpSize[i]; i++) {
upsized[i] = toupper(toUpSize[i]);
}
return upsized;
}
I think you either write i< length in the for loop, instead of toUpSize[i] as:
for (int i = 0; i < length; i++) {
upsized[i] = toupper(toUpSize[i]);
}
Or pass toUpSize as null-terminated string if you want to write toUpSize[i] in the for loop condition. If you do so, then you've to put \0 at the end of upsized after you exit from the loop, at index i for which toUpSize[i] is \0. And to accomplish this, you've te move the definition of i outside the for loop, so that you can use it after you exit from the loop.
Null-terminated string is what which has \0 character at the end of the string.
char x[] = {'N', 'a', 'w', 'a', 'z' };
char y[] = {'N', 'a', 'w', 'a', 'z', '\0' };
Here, x is not a null-terminated string, but y is a null-teminated string.
If the strings are defined as:
char z[] = "Nawaz";
const char *s = "Nawaz";
Here z and s are null-terminated string, because both of them are created out of "Nawaz" which is a null-terminated string. Note that sizeof("Nawaz") would return 6, not 5, precisely because there is an \0 at the end of the string.
You need to null-terminate the returned array if you want to print it like a string. Make sure that it ends with a null-terminator. Depending on how you calculate the length argument you may need to add extra space for it to the array. You may also want to make sure that the array that you pass in is null-terminated.
You need to add the termination char:
char * convertToUppercase (char* toUpSize, int length) {
std::cout << "ToUpsize: " << toUpSize << "\nLength: " << length << "\n";
char * upsized = new char[length];
int i;
for (i = 0; toUpSize[i]; i++) { // stops when you get toUpSize[i]==0
upsized[i] = toupper(toUpSize[i]);
}
upsized[i] = '\0'; //add termination
return upsized;
}
Your code assumes length to be the length of the allocated array, not the length of the string. strlen(toUpSize) counts the chars that are not '\0' from position 0 in toUpSize.
E.g.: strlen("abc\0def") -> 3
sizeof("abc\0def") -> 8!
Why are you even bothering with char pointers? This is C++, not C.
#include <string>
#include <algorithm>
#include <cstring>
#include <iostream>
std::string to_upper_case(std::string str)
{
std::transform(str.begin(), str.end(), str.begin(), toupper);
return str;
}
int main()
{
std::cout << to_upper_case("hello world\n");
}
If you decide to stick to the C solution, reserve one more char for the NUL terminator and put it there:
char * upsized = new char[length + 1]; // note the +1
upsized[length] = 0;