0

I have piece of code here.

void MyString::rm_left_space(char *s){
    int size = getSize(s);
    char s2[size];
    char *s1=&s2[0];
    int i=0;
    while(*(s+i)==' '){
        i++;
    }
    for (int k=i,l=0; k<size; k++) {//start from i, discarding spaces
        *(s1+l) = *(s+k);
        l++;
    }
    s=s1;
}

void MyString::rm_right_space(char *s){
    int countSpacesfromLast=0;
    int size = getSize(s);
    int j=size-1;
    while(*(s+j)==' '){
        countSpacesfromLast++;
        j--;
    }

    char *s2=new char[size-countSpacesfromLast];
    for (int t=0; t<size-countSpacesfromLast; t++) {
        *(s2+t)=*(s+t);
    }
    s=s2;
}

void MyString::rm_space(char *s){
    rm_left_space(s);
    rm_right_space(s);
}

Where there is s=s1 and s=s2 assignment does not happen. How come pointer assignment is not working.

In rm_space method s is unchanged after function calls. Why?

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
Abhijeet
  • 689
  • 2
  • 10
  • 19
  • C++ doesn't really have [variable-length arrays](https://en.wikipedia.org/wiki/Variable-length_array). Is there a reason you're not using `std::string`? – Some programmer dude Apr 19 '18 at 07:15
  • As for your problem, as any [good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282) should have told you, arguments are by default passed *by value*. Meaning they are *copied* into local variables in the functions. And modifying a copy will not modify the original. – Some programmer dude Apr 19 '18 at 07:16
  • Lastly, remember that local variables inside a function have a life-time of that function *only*. Pointers to them will become invalid as soon as the function returns and the local variables go out of scope. – Some programmer dude Apr 19 '18 at 07:17
  • I think the most important thing to understand about pointers is that there is nothing special about them. – molbdnilo Apr 19 '18 at 07:43
  • I know all this ... but when i say the pointer thing i got confused. `char *s` when you are passing `int m` and things like that i know. – Abhijeet Apr 19 '18 at 08:48

2 Answers2

0

In rm_space method s is unchanged after function calls. Why?

Because s is passed by value. In other words - it's not the variable s that is passed but the value that s holds. The variable s in the called function and the variable s in the calling function are two different variables. Consequently, changes made to one of them does not change the other.

If you want to change s in the calling function inside the called function, you need to use call-by-reference.

Something like:

void MyString::rm_left_space(char*& s){

However, notice that your code have a major problem as it seems you are trying to assign s2 in the called function to s in the calling function. You should never do that as s2 goes out of scope as soon as the function returns.

Example: Difference between pass-by-value and between pass-by-value

This simple program uses pass-by-value

#include <iostream>

void foo(int x)
{
  x = 42;
  std::cout << "Inside foo: x=" << x << std::endl;
}

int main()
{
  int x = 21;
  std::cout << "Before foo: x=" << x << std::endl;
  foo(x);
  std::cout << "After foo: x=" << x << std::endl;
  return 0;
}

The output is

Before foo: x=21
Inside foo: x=42
After foo: x=21    // notice x didn't change

because x in foo and in main are two different variables.

This simple program uses pass-by-reference

#include <iostream>

void foo(int& x)   // Notice the &
{
  x = 42;
  std::cout << "Inside foo: x=" << x << std::endl;
}

int main()
{
  int x = 21;
  std::cout << "Before foo: x=" << x << std::endl;
  foo(x);
  std::cout << "After foo: x=" << x << std::endl;
  return 0;
}

The output is

Before foo: x=21
Inside foo: x=42
After foo: x=42   // notice that x changed

because now x inside foo is a reference to x in main

These examples used int but exactly the same applies for pointers.

Example: Using pointers

#include <iostream>

int x = 21;
int y = 5;

void foo(int* p)
{
  *p = 42;
  p = &y;
  std::cout << "Inside foo:  p = " << p << std::endl;
  std::cout << "Inside foo: *p = " << *p << std::endl;
}

int main()
{
  int* p = &x;
  printf("%p\n", (void*)p);
  std::cout << "Before foo:  p = " << p << std::endl;
  std::cout << "Before foo: *p = " << *p << std::endl;
  foo(p);
  std::cout << "After foo :  p = " << p << std::endl;
  std::cout << "After foo : *p = " << *p << std::endl;

  return 0;
}

Output:

Before foo:  p = 0x60106c
Before foo: *p = 21
Inside foo:  p = 0x601070
Inside foo: *p = 5
After foo :  p = 0x60106c  // Pointer value did NOT change
After foo : *p = 42        // Pointed to value DID change

Replacing

void foo(int* p)

with

void foo(int*& p)

will give:

Before foo:  p = 0x60106c
Before foo: *p = 21
Inside foo:  p = 0x601070
Inside foo: *p = 5
After foo :  p = 0x601070  // Pointer value DID change
After foo : *p = 5         // Consequently, the pointed to value also changed
Community
  • 1
  • 1
Support Ukraine
  • 42,271
  • 4
  • 38
  • 63
  • @Abhijeet It makes no difference that you use pointers. Inside the function you can change the memory that the pointer points to but you can **not** change the value of the pointer. – Support Ukraine Apr 19 '18 at 08:10
  • I understand the above code with `int` and others. But I am passing a `char *s` from the calling function to the called function.. It is a pointer right...? – Abhijeet Apr 19 '18 at 08:10
  • @Abhijeet yes, it's a pointer in your case. It seems you are confused about a) What a **pointer points to** and b) the **value of a pointer**. Those are two very different things. – Support Ukraine Apr 19 '18 at 08:12
  • lets say below `int main(){ char[] s[10]; char *ss=&s[0]; rm_space(ss); }` is this not pass by reference? since i am sending a pointer to an array – Abhijeet Apr 19 '18 at 08:14
  • ooooo i understand... so the value of the pointer is replaced when the function call happens you say.... which then is sent to `rm_space("blablahblah");` Then the function gets called right? – Abhijeet Apr 19 '18 at 08:19
  • @Abhijeet I added an extra example. Hope it'll make it more clear. – Support Ukraine Apr 19 '18 at 08:33
  • I understood this today. – Abhijeet May 18 '18 at 01:18
0

I am new to StackOverflow, if there's any mistake, please Kindly judge me

I am not sure that whether I was misunderstand what you mean, so if there's any misunderstanding, please let me know.

I guess you want to do remove left space in a string, right?

e.g.

"  Hello" --> "Hello"

if so, here is my version

#include <iostream>
using namespace std;

#define SIZE 7
void rm_left_space(char* s){
    int size = SIZE; //Because I don't know how to getSize, so I use fixed size instead
    char s2[size]; 
    char *s1 = &s2[0];
    int i = 0;
    while(*(s+i) == ' '){
        i++;
    }
    cout << i << endl;
    for (int k=i,l=0; k<size; k++) {//start from i, discarding spaces
        *(s1+l) = *(s+k);
        l++;
    }
    s=s1; // <-- Shallow copy 
}

void rm_left_space_2(char* s){
    int size = SIZE;
    char *s2 = new char[SIZE]; <-- you should use dynamic array instead of static array 
    int space_num = 0;
    while(*(s+space_num) == ' '){
        space_num++;
    }
    for (int i = 0; i < SIZE; i++){
        s2[i] = s[(i + space_num)%size];
    }

    // s = s2; // <--- shallow copy

    for (int i = 0; i < SIZE; i++){     // You should copy whole array 
        s[i] = s2[i];
    }
}


int main(){

    char s[] = "  hello";
    cout << s << endl;

    rm_left_space_2(s);

    cout << s << endl;



    return 0;
}

The output:

  hello
hello

Also, you could check the post, static array vs dynamic array in C++