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
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).
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;
}
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.
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;
// ...
}
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;
}
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.
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++.
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
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
Related
A beginner's question I couldn't find answered online, likely because I don't know the terminology.
I want to call one of a list of procedures based on a computed index value. That is, given a '1', invoke firstProc(), '2' invokes secondProc() and so on.
All the procedures are void functions with no arguments.
I can implement that with switch/case, but what I'd prefer is something like:
void* action[2] {*firstProc, *secondProc};
(This compiles, but warns: invalid conversion from 'void (*)()' to 'void*')
and then later:
action[get_index()]();
The compiler objects that 'action' can't be used as a function.
This must be possible, right? I've tried several variations but I can't get past the use of the selected ('action[index]') as a function.
There are two equivalent ways to do what you want. The explanation is given as comments in the code snippets.
Method 1
#include <iostream>
void foo()
{
std::cout << "Hello";
}
void foo2()
{
std::cout << " wolrd!";
}
int main()
{
void (*a)() = foo;// a is a pointer to a function that takes no parameter and also does not return anything
void (*b)() = foo2;// b is a pointer to a function that takes no parameter and also does not return anything
//create array(of size 2) that can hold pointers to functions that does not return anything and also does not take any parameter
void (*arr[2])() = { a, b};
arr[0](); // calls foo
arr[1](); //calls foo1
return 0;
}
Method 1 can be executed here.
In method 1 above void (*a)() = foo; means that a is a pointer to a function that takes no parameter and also does not return anything.
Similarly, void (*b)() = foo2; means that b is a pointer to a function that takes no parameter and also does not return anything.
Next, void (*arr[2])() = { a, b}; means that arr is an array(of size 2) that can hold pointers to functions that does not return anything and also does not take any parameter.
Method 2
#include <iostream>
void foo()
{
std::cout << "Hello";
}
void foo2()
{
std::cout << " wolrd!";
}
int main()
{
//create array(of size 2) that can hold pointers to functions that does not return anything
void (*arr[2])() = { foo, foo2};
arr[0](); // calls foo
arr[1](); //calls foo1
return 0;
}
Method 2 can be executed here.
You need the correct syntax for your function pointer array. void(*func_ptr[])().
Example:
void func1() { std::cout << "Hallo" << std::endl; }
void func2() { std::cout << "World" << std::endl; }
// if you need a different signature for your functions like:
int func3(int n) { std::cout << "n1 " << n << std::endl; return n*2; }
int func4(int n) { std::cout << "n2 " << n << std::endl; return n*3; }
int main()
{
// array of function pointer which
// have no parameter and void as return value
void(*func_ptr[])()={ func1, func2 };
for ( unsigned int idx = 0; idx<2; idx++ )
{
func_ptr[idx]();
}
// array of function pointers with int return value and int as
// parameter
int(*func_ptr2[])(int)={ func3, func4 };
for ( unsigned int idx = 0; idx<2; idx++ )
{
std::cout << "retval: " << func_ptr2[idx](6) << std::endl;
}
}
I've stopped using function pointers (though they still can be useful).
I usually use std::function (and lambdas) when working with functions
Code for arrays of functions then look like this.
I used std::vector but std::array for fixed size should work fine too.
#include <vector>
#include <functional>
#include <iostream>
void some_function()
{
std::cout << "some function\n";
}
int main()
{
// std::function, abstraction of a function, function signature = template parameter, so void () is function returning a void, no parameters
// std::vector, runtime resizable array
// constructor : 4 time a lambda function printing out hello world.
std::vector<std::function<void()>> functions(4, [] { std::cout << "Hello World!\n"; } );
// easy syntax to assign an existing function to an index
functions[1] = some_function;
// replace a function in the vector with another one (lambda)
functions[2] = [] { std::cout << "booh\n"; };
// call function at index 0
functions[0]();
std::cout << "\n\n";
// or loop over all the functions and call them (classic for loop)
for (std::size_t n = 0; n < functions.size(); ++n) functions[n]();
std::cout << "\n\n";
// or loop over all the functions (range based for loop)
for (const auto& function : functions) function();
return 0;
}
I wanted a simple class which would encapsulate a pointer and a size, like C++20's std::span will be, I think. I am using C++ (g++ 11.2.1 to be precise)
I want it so I can have some constant, module-level data arrays without having to calculate the size of each one.
However my implementation 'works' only sometimes, dependent on the optimization flags and compiler (I tried on godbolt). Hence, I've made a mistake. How do I do this correctly?
Here is the implementation plus a test program which prints out the number of elements (which is always correct) and the elements (which is usually wrong)
#include <iostream>
#include <algorithm>
using std::cout;
using std::endl;
class CArray {
public:
template <size_t S>
constexpr CArray(const int (&e)[S]) : els(&e[0]), sz(S) {}
const int* begin() const { return els; }
const int* end() const { return els + sz; }
private:
const int* els;
size_t sz;
};
const CArray gbl_arr{{3,2,1}};
int main() {
CArray arr{{1,2,3}};
cout << "Global size: " << std::distance(gbl_arr.begin(), gbl_arr.end()) << endl;
for (auto i : gbl_arr) {
cout << i << endl;
}
cout << "Local size: " << std::distance(arr.begin(), arr.end()) << endl;
for (auto i : arr) {
cout << i << endl;
}
return 0;
}
Sample output:
Global size: 3
32765
0
0
Local size: 3
1
2
3
In this case the 'local' variable is correct, but the 'global' is not, should be 3,2,1.
I think the issue is your initialization is creating a temporary and then you're storing a pointer to that array after it has been destroyed.
const CArray gbl_arr{{3,2,1}};
When invoking the above constructor, the argument passed in is created just for the call itself, but gbl_arr refers to it after its life has ended. Change to this:
int gbl_arrdata[]{3,2,1};
const CArray gbl_arr{gbl_arrdaya};
And it should work, because the array it refers to now has the same lifetime scope as the object that refers to it.
I'm having a trouble manipulating a pointer inside a class.
#include <iostream>
using namespace std;
class myClass {
public:
void modifyPointer(float *pointer);
};
void myClass::modifyPointer(float *pointer) {
pointer = new float[3];
pointer[0] = 0;
pointer[1] = 1;
pointer[2] = 2;
cout << "Address: " << pointer << endl;
}
int main()
{
float* pointer;
myClass object;
object.modifyPointer(pointer);
cout << "Address: " << pointer << endl;
cout << "Values: " << pointer[0] << "," << pointer[1] << "," << pointer[2]
<< std::endl;
return 0;
}
When I print the pointer inside the class I get its address, but in the main program I get a 0 address and a seg fault when printing values. What am I wrong in how to modify this pointer?
You are taking the pointer by copy, so you don't see the changes in main. You need to take the pointer by reference, like this:
void myClass::modifyPointer(float * &pointer) {
pointer = new float[3];
// ...
}
You have to change the declaration of this function as well, of course.
Here's a working demo.
Pointers are just like any other objects. Passing an object as an argument by value creates a copy of that object. This means the original pointer in main() remains unaffected. And since it is unaffected and not initialized, accessing an array out of bounds with pointer[any_index] results in undefined behavior. Pass by reference instead:
void modifyPointer(float*& pointer)
I have a test function that takes an array as an argument. And I have an array of pointers. Can someone explain why I need to deference the pointer to an array of pointers when I pass it?
void test(States a[]){
cout << a[0].name << endl;
cout << a[1].name << endl;
}
Calling test():
States *pStates[MAX_STATES];
test(*pStates); //Or test(pStates[0])
//Can't do test(pStates);
You won't need to dereference if the arguments of test function expect so
void test(States *a[]);
But in your case, clearly the argument type is States [], so you need to pass a pointer.
You may want to consider rewriting test function as:
void test(States *a[]){
cout << a[0]->name << endl;
cout << a[1]->name << endl;
}
Use this instead:
void test(States* a[]){
cout << a[0]->name << endl;
cout << a[1]->name << endl;
}
And you won't need to dereference it...
The declaration of pStates declares an array of pointers. Not a pointer to an array.
However the function void test(States a[]); expects an array of objects (States objects).
You can't just cast one to the other.
#include <iostream>
typedef struct {
int name;
} States; //Surely this should be called State (not plural)
const size_t MAX_STATES=2;
void test(States a[]){
std::cout << a[0].name << std::endl;
std::cout << a[1].name << std::endl;
}
int main() {
States lFirst;
States lSecond;
lFirst.name=1;
lSecond.name=7;
//Here's what you had.
States*pStates[MAX_STATES];
//Now initialise it to point to some valid objects.
pStates[0]=&lFirst;
pStates[1]=&lSecond;
//Here's what you need to do.
States lTempStates[]={*pStates[0],*pStates[1]};
test(lTempStates);
return EXIT_SUCCESS;
}
Please see here https://stackoverflow.com/help/mcve
I want to access the vector in the "manipulatevector" function below the same way as i access an array with vector[i] and not vector->at(i) in the code below. I have tried to pass the vector directly, and not a pointer as can be done with arrays. But this seem to corrupt the program. Any ideas how this can be achieved? Im new to using the std library, as i mostly have experience from C.
#include <vector>
#include <iostream>
#define vectorsize 5
struct st_test {
int ii;
float dd;
};
void manipulatevector(std::vector<struct st_test> *test) {
test->resize(vectorsize);
for(int i=0;i<vectorsize;i++) {
test->at(i).dd = i*0.4f;
test->at(i).ii = i;
}
}
void manipulatearray(struct st_test test[vectorsize]) {
for(int i=0;i<vectorsize;i++) {
test[i].dd = i*0.4f;
test[i].ii = i;
}
}
void main() {
std::vector<struct st_test> test1;
manipulatevector(&test1);
struct st_test test2[vectorsize];
manipulatearray(test2);
std::cout << "Vector" << std::endl;
for(int i=0;i<vectorsize;i++) {
std::cout << test1.at(i).dd << std::endl;
}
std::cout << "Array" << std::endl;
for(int i=0;i<vectorsize;i++) {
std::cout << test2[i].dd << std::endl;
}
}
Have you tried passing the vector as a reference?
void manipulatevector(std::vector<struct st_test> &test) {
test.resize(vectorsize);
for(int i=0;i<vectorsize;i++) {
test[i].dd = i*0.4f;
test[i].ii = i;
}
}
and
std::vector<struct st_test> test1;
manipulatevector(test1);
You can simply use (*test)[i] instead of test->at(i).
This is not actually the same behavior (at vs operator[]), but you are probably already aware of that.
Pass it as a reference instead of a pointer.
void manipulatevector(std::vector<struct st_test> &test) {
You then use . instead of ->, and things like the overloaded [] operator are usable.
Change the signature of void manipulatevector(std::vector<struct st_test> *test) to void manipulatevector(std::vector<struct st_test>& test). Then you can use the operator[] on the vector.
You can pass the vector by reference and use the [] operator:
void manipulatevector(std::vector<struct st_test>& test) {
test.resize(vectorsize);
for(int i=0;i<vectorsize;i++) {
test[i].dd = i*0.4f;
test[i].ii = i;
}
}
When you passed the vector directly, I presume you passed it by value:
void manipulatevector(std::vector<struct st_test> test) {
which meant any changes made inside manipulatevector() would not be seen by the caller. This would mean:
for(int i=0;i<vectorsize;i++) {
std::cout << test1.at(i).dd << std::endl;
}
would throw a std::out_of_range error, from test.at(i), as test1 would not have vectorsize elements, but zero elements. As there is no exception handling in main() this would have caused the program to crash.
There are different options here. You can pass the vector by reference, which is the simplest and cleaner in code:
void function( std::vector<type>& v )
Now, in some shops the style guide requires that if you are going to modify an argument you pass it by pointer as that makes it explicit at the place of call. In that case there are different options to call operator[]:
void function( std::vector<type> *v ){
(*v)[0] = .... // dereference first
v->operator[](0) = .... // explicitly cal the operator
std::vector<type>& vr =*v;
vr[0] = .... // create reference and use that
The first two are equivalent, with the first being arguably easier to read. The second is equivalent to the first one in that it dereferences the pointer and then accesses the operator, but you are explicitly giving a name to the reference, so it can be reused in the function without having to dereference in all uses. While this technically creates an extra variable, the compiler will most probably optimize the reference away.