17

I am passing a char array by reference but when I return from function and print the array, it displays nothing. What am I doing wrong?

#include <iostream>

using namespace std;

void func(char []);
int main()
{
   char a[100];
   func(a);

   cout << a<<endl;
   return 0;
}

void func(char *array)
{
   array="Inserting data in array a";
   cout << array<<endl;
}

Regards

Naruto
  • 1,710
  • 7
  • 28
  • 39
  • 1
    Where do you insert the data into the array? Can you show that code? – juanchopanza Oct 20 '12 at 11:09
  • Y are you creating an array of 100 char and storing only 1 char...do you want to store multiple char – Anirudha Oct 20 '12 at 11:17
  • make sure you know these points before you read the answers. 1.'a' is an address.you are copying it to 'array'.Every thing is fine till now. 2."Inserting data in array" this string yields an address.In the func() function you are overwriting 'array' with this address. – tez Oct 20 '12 at 11:24
  • @tez: No, 'a' is not an address. 'a' is an array of 100 chars. It can, in many situations, be implicitly converted to a pointer. But it is not a pointer itself. – Benjamin Lindley Oct 20 '12 at 11:33
  • @BenjaminLindley But isn't 'a' a pointer to the first element of the array of 100 elements?? – tez Oct 20 '12 at 12:08
  • @tez: No, it's not. It can be implicitly converted to one, as is the case when it is passed to a function that takes a pointer. Or when it is assigned to a pointer. Here is a little code snippet I made a few days ago to demonstrate to someone that arrays are not pointers: http://ideone.com/vb6Nj – Benjamin Lindley Oct 20 '12 at 12:18
  • @BenjaminLindley Wow,Thanks.Nice use of sizeof().But a small question.char a[] = "hello world". Is 'a' converted to a pointer or is it still an array of chars?Does "hello world always yield a pointer??Sorry for spamming – tez Oct 20 '12 at 12:55
  • 1
    @tez: No, 'a' is still an array of chars in that case. 12 chars to be exact (the null-terminator is implicit). A string literal, such as "hello world", also is a char array in fact. But it's an array that exists in read-only memory. So you cannot modify it. When you do this: `char a[] = "hello world";` -- The array "hello world", which resides in read-only memory, is copied to the local char array 'a'. So no, a string literal does not always yield a pointer. It does so in the same places that an array does, because it is an array. – Benjamin Lindley Oct 20 '12 at 13:03

9 Answers9

12

What you can probably do is:

void func( char (& array)[10] ) {

}

According to the Spiral Rule, that is translated to: a reference (&) to an array of length 10 ([10]) characters (char).

David G
  • 94,763
  • 41
  • 167
  • 253
8

You're not passing the array by reference (nor should you, it will do you no good here). You are passing a pointer to its first element. You then reassign that pointer to point to something else inside the function. This has no effect on the array. If you want to change the contents of the array, then you need to copy data to the place that the pointer points to. You can use strcpy or similar for that:

strcpy(array, "Inserting data in array a");

As a side comment, but a very important one. We don't need to deal with things like this in C++ anymore. That's how you do things in C. Here's how we do things in C++:

#include <string>
#include <iostream>

void func(std::string & str)
{
    str = "Inserting data into the string";
    std::cout << str << std::endl;
}

int main()
{
    std::string a;
    func(a);
    std::cout << a << std::endl;
}
Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
  • 1
    than How can I pass an array by reference – Naruto Oct 20 '12 at 11:11
  • 1
    @UmerFarooq: You could change your function signature to `func(char (&array)[100])` -- But that's useless in this case. You can't assign to arrays, you'll still have to copy using something like strcpy. – Benjamin Lindley Oct 20 '12 at 11:13
  • I guess I don't need to do reference thing as you showed. I am passing the array by reference because When I took input from user, the contents of the array changed. – Naruto Oct 20 '12 at 11:17
  • Can you tell me why exactly my way of changing data in array inside func() is not working. – Naruto Oct 20 '12 at 11:18
  • @UmerFarooq: The first four sentences in my answer explain exactly that. – Benjamin Lindley Oct 20 '12 at 11:19
  • Ok. so I passed a reference of array a by func(char (&array)[100]); but when I do array="inserting dta in array a", I get error. – Naruto Oct 20 '12 at 11:36
  • @UmerFarooq: Exactly. Like I said in my comment, you can't assign to arrays, you'll still have to copy using something like strcpy. – Benjamin Lindley Oct 20 '12 at 11:38
8

You can pass a pointer by reference. To do this you need to use the following syntax:

void func(char *&array)
{
    // ....
}

Inside the function you use this parameter as a regular pointer. If the value that this pointer is pointing at is modified, these changes will be visible outside.

Kirill Kobelev
  • 10,252
  • 6
  • 30
  • 51
  • You can do that, but this is no use in trying to pass an array to a function. – Benjamin Lindley Oct 20 '12 at 11:20
  • 2
    This is not going to work with the way the `main` passes the value of `a` to the function: the code is not going to compile with the message "invalid initialization of non-const reference of type ‘char*&’ from a temporary of type ‘char*’" – Sergey Kalinichenko Oct 20 '12 at 11:20
  • @dasblinkenlight, You are right. Please, consider my note as something stand alone. – Kirill Kobelev Oct 20 '12 at 11:23
4

I used the answers above but I had to extend it, so I could print out the array's actual size like so:

template<size_t n> void foo(char (&array)[n])
{
    // ...
    std::cout << "array size: " << n << std::endl;
    // ...
}
radato
  • 840
  • 9
  • 27
2

Try the following:

void function(char* MyArray)
{
    MyArray = "Hello World";
    std::cout << "Address of MyArray inside function: " << (void*)MyArray << std::endl;
}

int main()
{
    char MyArray[10];
    std::cout << "Address of MyArray outside function: " << (void*)MyArray << std::endl;
    function(MyArray);
    std::cout << "Address of MyArray outside function: " << (void*)MyArray << std::endl;

    std::cin.get();
    return 0;
}

With this you will see that the pointer to your array is only a copy inside the function. With assigning "Hello World" you only change the adress of the copy but not the adress of your array in the main function.

This example would actually work because this way you dont have copy of your pointer within the function:

void function(char** MyArray)
{
    *MyArray = "Hello World";
    std::cout << "Address of MyArray inside function: " << (void*)*MyArray << std::endl;
}

int main()
{
    char* MyArray = 0;
    std::cout << "Address of MyArray outside function: " << (void*)MyArray << std::endl;
    function(&MyArray);
    std::cout << "Address of MyArray outside function: " << (void*)MyArray << std::endl;

    std::cin.get();
    return 0;
}

But this is still bad style. When working with character arrays you should do something like this:

void function(char* MyArray)
{
    strcpy(MyArray, "Hello World");
    std::cout << "Address of MyArray inside function: " << (void*)MyArray << std::endl;
}

int main()
{
    char* MyArray = 0;
    MyArray = new char[15];

    std::cout << "Address of MyArray outside function: " << (void*)MyArray << std::endl;
    function(MyArray);
    std::cout << "Address of MyArray outside function: " << (void*)MyArray << std::endl;

    delete [] MyArray;

    std::cin.get();
    return 0;
 } 

But as others mentioned I would use std::string and pass it by reference also instead of using character arrays. Because character arrays are unsafe compared to std::string. Like this:

void function(std::string& MyString)
{
    MyString = "Hello World";
}

int main()
{
    std::string MyString;
    function(MyString);

    std::cin.get();
    return 0;
}
roohan
  • 731
  • 3
  • 8
  • 15
  • what if instead of `std::string MyString;` i do `char MyString[50]` and pass to function by casting it like '(std::string)(MyString)'. IS it ok? if not what is the disadvantage ? – BreakBadSP Nov 17 '18 at 07:46
0

You are passing a pointer to an array (func (char* array)) and then inside the function you are changing the pointer's value to point to the static string.

You either need to copy the new data into the array by means of strcpy() or pass the pointer to the array by reference:

void func(char*& array); // reference to pointer

Or:

strcpy(array, "data");

Better yet use std::vector<> or std::string instead.

mauve
  • 1,976
  • 12
  • 18
0

Reference to native array is one of the very powerful C++ weapons. Plus templates. Here is one, perhaps non trivial but still simple example.

// set all element of a given native array reference 
// to the same value
// return the reference to the same array
    template<typename T, size_t N, typename array_type = T[N] >
    inline
        array_type&  /* return reference to T[N] */
        all_val 
         (  T(&arf)[N],  /* arg reference to T[N] */
            T val   )
    {
        // range for() works on native arrays
        // begin(arf) / end(arf)
        // work as expected
        for (auto & elem : arf) {
            elem = val ;
        }
        // array can not be returned by value
        // but this is allowed in standard C++
        // return type is native array reference
        return arf;
    }

When using the above, one should think and preserve returned type as native array reference.

        using charray_type = char[0xF];
        charray_type charray;
        // decaying to pointer to T*
        // you do not want this
        auto pointer_to_char = all_val(charray, '*');
        // you do want this
        // preserving the ref to array
        charray_type& charray_ref = all_val(charray, '*');
        // normal native arr usage
        charray_ref[0] = '*';
        assert(charray[0] == charray_ref[0]);

I think this is rather simple and unique to standard C++.

Chef Gladiator
  • 902
  • 11
  • 23
0

I know this post is kind of old but I recently came across a style of passing char array as a reference and implemented it in your example ..

I have no Idea why when passing a char array as a reference you use [0] as the array index but this code works .

I spend allot of time looking around the web on how to do this so maybe it helps someone

#include <iostream>

using namespace std; 

void  func(char arr[3]);

int main()
{
  char a[3];
  a[0] ='a'; 
  a[1] ='b';
  a[2] ='c';

 //passing the char array as a refrence
 func(&a[0]);

 cout<< "checking the values outside of the func"<<endl;
 cout << a<<endl;
 return 0;
}

void func(char arr[3])
{
   cout<<"Inserting data in array a in the function " <<endl;
   cout << &arr[0]<<endl;
}

The main idea behind passing an object as a reference is to not have a copy of the object as this could use up memory resources . So in the case of char array you might have very large array so it would be inefficient to send the whole char array objet as an argument . This is why we would pass by a reference instead

JonoJames
  • 1,117
  • 8
  • 22
-1

error first line iostream.h ... and secondly you are not inserting any element into array...and you are passing a in your function, you have to pass address of your array into that function, but before that rewrite the code to have something in your array

agaonsindhe
  • 447
  • 1
  • 5
  • 13