Pass value by pointer error - c++

I don't understand why is crashing. I send a pointer to an array, alloc that array and then modify array. What is the problem?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void f(unsigned char *data) {
data = (unsigned char *)malloc(200);
}
int main() {
unsigned char *data = nullptr;
int i;
f(data);
memset(data, 0, 200);
}

You are passing data by value to f().
f() sets the value of its parameter.
Because the parameter was passed by value, this does absolutely nothing to the data variable in main(). f() leaks the allocated memory, and when it returns, main()'s data is still nullptr.
You should pass it by reference:
void f(unsigned char *&data)
Or, better yet, return it. f() doesn't need the parameter.
unsigned char *f() {
return (unsigned char *)malloc(200);
}

Change
void f(unsigned char *data) { // ....
to
void f(unsigned char *&data) { // ....
// ^
}
or
void f(unsigned char **data) {
*data = (unsigned char *)malloc(200);
}
and call
f(&data);
// ^
It's all about passing a reference to the data pointer to be initialized from within the function.
Your example passes data by value, and doesn't change the pointer outside of the function.

The call to f does not change the value of the variable data defined in main, as you seem to expect it to. It changes the value of the data defined in f, but because parameters are passed by value, that has no effect on the data defined in main.

Related

How to add data in an array? What's wrong with this c++ code? [error: subscript of pointer to incomplete type 'void']

I have this question and I don't know where the problem is.
Correct the code below:
void AddData(void *data, unsigned int value, int index){
data[index] = value;
}
int main(){
unsigned int array[20];
AddData(array, 10, 5);
return 0;
}
error: subscript of pointer to incomplete type 'void'
How should I modify the code?
Why put "void *data" in the function AddData() rather than "int data[20]"?
void* is a pointer to almost anything, and the compiler just doesn't know what it might point to. It's not possible to dereference a void* pointer without casting it to its correct pointer type first.
In C++, it's very uncommon with void* pointers, because you can use templates to get the correct and actual type instead:
template<typename T>
void AddData(T *data, unsigned int value, int index){
data[index] = value;
}
Now, when being called, the compiler will deduce the type and use it instead of T, so in effect the argument-type becomes unsigned int* (for the example in the question).
With all this said, I recommend you don't use plain arrays, and definitely not pointers.
For arrays, use either std::array or std::vector instead:
template<typename T>
void AddData(T& data, unsigned int value, size_t index){
data[index] = value;
}
int main(){
std::array<unsigned int, 20> array;
AddData(array, 10, 5);
}
[Note that I pass the std::array object by reference and not by value in this example. Also note I changed the type of the index argument]
data[index] is the same as *(data + index) and for that to work, the size of the elements must be known. In this case, since data is pointing at an unsigned int, you need to cast it to unsigned int*
void AddData(void *data, unsigned int value, int index){
static_cast<unsigned int*>(data)[index] = value;
}
int main(){
unsigned int array[20];
AddData(array, 10, 5);
return 0;
}
How should I modify the code?
I would suggest making it a function template using a std::vector instead:
#include <vector>
template<class T>
void AddData(std::vector<T>& data, const T& value, std::size_t index){
data[index] = value;
}
int main(){
std::vector<unsigned int> array(20);
AddData(array, 10, 5);
}
Why put void *data in the function AddData() rather than int data[20]?
Presumably it's inherited from C code and they cast the void* to whatever type the array is holding.

Issue while passing pointer to constant as an argument

In this eg,using call by address concept in order to retrieve all the data changes which is happening in the function call...
In main(),
i)passing two arguments
i)int pointer
ii)pointer to constant -> which cannot change the value it is holding...
ii)Changing the values of int * and assigning some values to const void * in the function calls.
*Finally i'm trying to print the values in main()
*getting the int pointer values properly(no issues)
*getting the void pointer value as NULL..
Requirement:
Need to get the output in main() like this
main::ajskdffllagkdjdjdhdjhd(i mean to say that i need to print the void * values like this)
But i'm getting the value as main:: NULL
What shall i need to do inorder to get the expected output?
#include <stdio.h>
#include <stdlib.h>
void func(int *len,const void *pBuf);
void func2(int **len,const void **pBuf);
void func3(int ***len,const void ***pBuf);
int main()
{
int len = 0;
const void *pBuf;
printf("len b4 ::%d\n",len);
printf("%p\n",&pBuf);
func(&len,&pBuf);
printf("len after::%d\n",len);
printf("%p\n",&pBuf);
printf("main::%s\n",(const char *)pBuf);
return 0;
}
void func(int *len,const void *pBuf)
{
*len = 20;
printf("func1 :: %p\n",&pBuf);
func2(&len,&pBuf);
}
void func2(int **len,const void **pBuf)
{
printf("func2::%p\n",&pBuf);
**len = 30;
func3(&len,&pBuf);
}
void func3(int ***len,const void ***pBuf)
{
const void *pMy = "ajskdffllagkdjdjdhdjhd";
**pBuf = pMy;
printf("func3::%p\n",&pBuf);
printf("func3::%s\n",(const char *)**pBuf);
***len = 40;
}
Output:
len b4::0
0x7fffa9c51468
func1 :: 0x7fffa9c51440
func2::0x7fffa9c51420
func3::0x7fffa9c513f0
func3::ajskdffllagkdjdjdhdjhd
len after::40
0x7fffa9c51468
main::(null)
You are right with the string literal. Sorry.
However, you need to change the address where pBuf points to:
void func(int *len,const void **pBuf)
{
*len = 20;
printf("func1 :: %p\n",pBuf);
func2(&len,&pBuf);
}
void func2(int **len,const void ***pBuf)
{
printf("func2::%p\n",pBuf);
**len = 30;
func3(&len,&pBuf);
}
void func3(int ***len,const void ****pBuf)
{
const void *pMy = "ajskdffllagkdjdjdhdjhd";
***pBuf = pMy;
printf("func3::%p\n",&pBuf);
printf("func3::%s\n",(const char *)***pBuf);
***len = 40;
}
len is an int. In order to change it, you need to call func() with the address of that int value.
pBuf is a pointer. To change the address where it points to, you need to call func() with the address of that pointer.
You are catching address of int with single pointer and catching the address of pointer also with single pointer.. This is problem. In functions, change *pBuf as **pBuf and **pBuf as ***pBuf and so on..

How to pass array of function pointers to another function

I have got 2 functions:
char* odwroc(char* nap, int n)
char* male(char* nap, int n)
I have defined a pointer to that kind functions
typedef char*(*pointerToFunction )( char*, int );
then in used that definition in main:
pointerToFunction ptr1 = odwroc;
pointerToFunction ptr2 = male;
but now I have to create a function which as a first parameter gets array of that pointers to function and I am stuck. I don't know how to define array of pointers to function and how the modyfikuj parameter list should look like.
void modyfikuj(char* pointerToFunction *pointerArray, int length, char* nap2, int n){
}
Try this:
pointerToFunction mojefunkcje[] = { odwroc, male};
modyfikuj( mojefunkcje, ...); // pass the array fo modyfikuj()
void modyfikuj( pointerToFunction* funtab, ...)
{
funtab[0]( string, liczba); // call odwroc( string, liczba)
funtab[1]( string, liczba); // call male( string, liczba)
}
Even though the above answer make sense, use of containers such as std::vector will give you more control when passing an array of similar type such as a pointer to a function. Please try below code snippet.
#include "vector"
using namespace std;
typedef char*(*pointerToFunction )( char*, int );
typedef vector<pointerToFunction> FUNCTION_VECTOR;
bool modyfikuj( FUNCTION_VECTOR& vecFunctionVector )
{
// The below checking ensures the vector does contain at least one function pointer to be called.
if( vecFunctionVector.size() <= 0 )
{
return false;
}
// You can have any number of function pointers to be passed and get it executed, one by one.
FUNCTION_VECTOR::iterator itrFunction = vecFunctionVector.begin();
FUNCTION_VECTOR::const_iterator itrFunEnd = vecFunctionVector.end();
char* cszResult = 0;
for( ; itrFunEnd != itrFunction; ++itrFunction )
{
cszResult = 0;
// Here goes the function call!
cszResult = (*itrFunEnd)( "Hello", 1 );
// Check cszResult for any result.
}
return true;
}
char* odwroc(char* nap, int n); // You will define this function somewhere else.
char* male(char* nap, int n); // You will define this function somewhere else.
int main()
{
FUNCTION_VECTOR vecFunctions;
// You can push as many function pointers as you wish.
vecFunctions.push_back( odwroc );
vecFunctions.push_back( male );
modyfikuj( vecFunctions );
return 0;
}

c++ pass char array to function and change it

I try to make a function that can change the content of a specified char array
void change_array(char *target)
{
target="hi";
}
int main()
{
char *a[2];
change_array(a[1]);
cout<<*(a[1]);
}
But then the content of a[1] stays at 0x0(void)
First, your function has a copy of the pointer passed to it, so there is no effect seen on the caller side. If you want to modify the function argument, pass a reference:
void change_array(char*& target) { ... }
// ^
Second, you cannot/should not bind a non-const pointer to a string literal. Use const char* instead.
void change_array(const char*& target) { ... }
// ^^^^^ ^
int main()
{
const char* a[2];
change_array(a[1]);
cout<<*(a[1]);
}
When you pass an argument to a function, it's normally passed by value, meaning its value is copied. If you want to change it you have to pass it by reference. The same goes for pointers, if you want to change a pointer then you need to pass it by reference as well:
void change_array(const char*& target) { ... }
You need to pass it as a reference:
void change_array(char*&target)
{
target="hi";
}
Otherwise, you will just change the local copy of target, which won't make any difference to the value outside of the function.
Try this design instead:
std::string get_string()
{
return "hi";
}
int main()
{
std::string a[2];
a[1] = get_string();
std::cout<< a[1];
}
Salient points:
return by value
use std::string

Increment the value of a pointer when sent as a parameter

I am stuck in the following pointer problem:
Say you have a function:
void Function (unsigned char *ubPointer)
{
ubPointer++;
}
int main (void)
{
unsigned char *PointerX;
Function( PointerX );
}
What I want is that the ++ is reflected in PointerX, without declaring it as a global variable.
Thank you very much.
In C++, pass your pointer by reference (and don't forget to specify a return type for your function):
void Function (unsigned char*& ubPointer)
// ^
{
ubPointer++;
}
This won't require any further change in the calling code. When returning from the function, the side-effects on ubPointer will be visible to the caller.
In C, you can achieve the equivalent result by passing a pointer to your pointer:
void Function (unsigned char** ubPointer)
// ^
{
(*ubPointer)++;
// ^^^^^^^^^^^^
}
This will require you to change the way you are calling your function:
int main()
{
unsigned char* p;
Function(&p);
// ^
}
Or, if you want to do it C-style
void Function (unsigned char **ubPointer)
{
(*ubPointer)++;
}
because
Function (unsigned char **ubPointer)
{
ubPointer++;
}
would be increasing the address pointed to.
void Function (unsigned char *ubPointer)
{
(*ubPointer)++;
}
int main (void)
{
unsigned char *PointerX;
Function( PointerX );
}
This is the correction