Passing pointer to an array of pointers - c++

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

Related

Modify pointer inside class

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)

Accessing the members of a struct referenced by a void pointer

I've got a function that takes a void pointer as a parameter. I want to pass this function a pointer to a struct, and then access the values of that struct within the function.
//the struct
struct s{
int val;
};
//the function tries to access the object
int callback(void* p_obj)
{
//try creating a new struct based on p_obj
s2 = *(struct s*)p_obj;
std::cout << "VALUE IN CALLBACK: ";
std::cout << s2.val << std::endl; //prints a big-ass int
return 0;
}
//main calls the function
int main()
{
s s1;
s1.val = 42;
void* p1 = &s;
//show some output
std::cout << "s1.val: ";
std:cout << s1.val << std::endl; //prints 42
//std::cout << "p1->val: ";
//std:cout << *(struct s*)p1->val << std::endl; //does not compile
s p2 = *(struct s*)p1;
std::cout << "p2.val: ";
std:cout << p2.val << std::endl; //prints 42
//call the function
callback(&p1);
return 0;
}
I would expect the output in the callback function to be
VALUE IN CALLBACK: 42
VALUE IN CALLBACK: 42
but, instead, I think it's printing a memory address
VALUE IN CALLBACK:1989685088
VALUE IN CALLBACK:1989685088
Trying to access the members of a void pointer directly results in an error.
int callback(void* p_obj)
{
std::cout << "VALUE IN CALLBACK: ";
std::cout << (struct s*)p_obj->val << std::endl;
}
error: 'void*' is not a pointer-to-object type
Why is this? How can I access the members of a struct that a void* is pointing to?
EDIT: Fixed some typos in the writeup
You have two errors:
*(struct s)p_obj needs to be *(struct s*)p_obj, as p_obj is not a structure object.
Because of operator precedence the expression (struct s*)p_obj->val is actually equal to (struct s*)(p_obj->val). Which means you try to dereference the void* pointer and cast the member val to struct s*.
You should do ((struct s*)p_obj)->val to cast the pointer p_obj.
And more typos: *void p_obj is very much wrong, it should be void* p_obj. Please take care to copy-paste your minimal, complete, and reproducible example, not retype is as that might add extra errors not in your real code, which distracts from the actual errors and problems.

Printing the address of member function

struct Widget {
void test() {}
};
int func() {}
int main() {
std::cout << &Widget::test << std::endl;
std::cout << Widget::test << std::endl;
std::cout << func << std::endl;
std::cout << &func << std::endl;
}
In this code only the second line of main function doesn't compile. The others print 1. Why does it print 1. Shouldn't print the address of function? And why second doesn't compile but first does?
Why does it print 1. Shouldn't print the address of function?
No. std::cout can print a void*, but there's no implicit conversion from function pointer types to void* (for neither regular function pointers nor pointer-to-member types). There's a conversion from function pointer types to bool though. That's what we end up with.
And why second doesn't compile but first does?
Because the standard requires you to use & to get the address of a member function.

Passing char array by reference

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

How can a template function 'know' the size of the array given as template argument?

In the C++ code below, the templated Check function gives an output that is not what I would like: it's 1 instead of 3. I suspect that K is mapped to int*, not to int[3] (is that a type?). I would like it to give me the same output than the second (non templated) function, to which I explicitly give the size of the array...
Short of using macros, is there a way to write a Check function that accepts a single argument but still knows the size of the array?
#include <iostream>
using namespace std;
int data[] = {1,2,3};
template <class K>
void Check(K data) {
cout << "Deduced size: " << sizeof(data)/sizeof(int) << endl;
}
void Check(int*, int sizeofData) {
cout << "Correct size: " << sizeofData/sizeof(int) << endl;
}
int main() {
Check(data);
Check(data, sizeof(data));
}
Thanks.
PS: In the real code, the array is an array of structs that must be iterated upon for unit tests.
template<class T, size_t S>
void Check(T (&)[S]) {
cout << "Deduced size: " << S << endl;
}