0

As far as I know, in C++ when you pass a non-pointer object to a method, it makes a copy of it to work with in the method. However in my program below, I pass a copy and yet my method actually edits the original character array. Why is this working? :/

#include <iostream>
#include <string>
 void Reverse(char s[], int sizeOfArray)
{
    for (int i = 0 ; i < sizeOfArray; i++)
    {
        s[i] = 'f';
    }

}
int main()
{
    char c[3] = {'g','t','r'};
    Reverse(c,3);
    for (int t = 0 ; t < 3; t++)
   {
      std::cout << c[t];
   }
    return 0;
 }

NOTE:

The output is fff

  • Because in C++, arrays are _not objects_. It does work with class and structure types containing arrays though, which is exactly what the C++11 `std::array` is. – Jan Hudec Mar 01 '14 at 10:29
  • On a side-note, this is the same in C. In C it's common to pass structures by pointer, but they _can_ be passed by value there too. – Jan Hudec Mar 01 '14 at 10:29
  • @JanHudec Depends on how you define the term "object". According to the C++ standard, arrays are definitely objects. – fredoverflow Mar 01 '14 at 10:31

5 Answers5

2

You cannot copy arrays by passing them to functions. The array "decays" into a pointer. Check for yourself by printing the variables' typeid:

#include <iostream>
#include <string>
void Reverse(char s[], int sizeOfArray)
{
    std::cout << typeid(s).name() << "\n";
    for (int i = 0 ; i < sizeOfArray; i++)
    {
        s[i] = 'f';
    }

}
int main()
{
    char c[3] = {'g','t','r'};
    std::cout << typeid(c).name() << "\n";
    Reverse(c,3);
    for (int t = 0 ; t < 3; t++)
   {
      std::cout << c[t];
   }
    return 0;
 }

Result:

char [3]
char *

Moral of the story:

Use std::vector.


Edit: I should mention that the exact result of the typeid name is implementation-defined. "char [3]" and "char *" is what I get with VC 2013. But the underlying issue is the same on every compiler, of course.

Christian Hackl
  • 27,051
  • 3
  • 32
  • 62
  • 2
    or use std::array in C++11 (if you want a fix sized array) – KoKuToru Mar 01 '14 at 10:05
  • Yes, but I still think one should use std::vector if there are no special requirements, and consider std::array only if it's needed (but then, it's better than raw arrays in roughly 99% of all cases, of courses). – Christian Hackl Mar 01 '14 at 10:09
0

void Reverse(char s[], int sizeOfArray)

Reverse(c,3);

>call by value

>call by reference

here you are doing call by reference operation that means you are passing address of c to int s[]

you are passing a reference of c to reverse function. this is called call by reference not call by value. thats why reverse function overriding your original input

java seeker
  • 1,246
  • 10
  • 13
0

Because char s[] is actually char * pointing to the first element of array. It means your function Reverse gets the first arg pointer but not copy of array.

If you want to get copy you should use memcpy first and pass new (copy) array to function.

0

C-array cannot be passed by copy.

It may be passed by reference as void Reverse(char (&a)[3])
or by its decayed pointer as you do void Reverse(char a[], int size) (which is the same as void Reverse(char* a, int size)).

You may use std::array (C++11) to have a more intuitive behaviour.

Jarod42
  • 203,559
  • 14
  • 181
  • 302
-1

if you declare an array then the variable holds the base address of that array, so here char c[3] means c holds the base address of the array c[3].

so, when you are passing Reverse(c,3); actually you are passing the base address.

rajenpandit
  • 1,265
  • 1
  • 15
  • 21