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
Related
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.
My question is how to translate the following example? Is this a function, that returns int pointer?
int* (*function)(int, (int (*k)(int *)));
And can I can't write program that use it?
Thanks in advance!
It is a function-pointer
The function returns a pointer to an int
The function's first arg is an int
The function's second arg is a function-pointer k
k returns an int
k takes a pointer to an int as argument
Sure you can use that in your program. It is not too unusual. There are much worse declarations i have seen.
I renamed your "function" to "F" for clarity. Then you can write:
int* (*F)(int, int (*kFunc)(int *) );
Alternative:
typedef int (*kFunc)(int *);
int* (*F)(int, kFunc);
There are a lot of ways to use pointer to a function, may be a pattern such as Factory could take advantage of the function pointer to create new objects.( Look here : http://www.codeproject.com/Articles/3734/Different-ways-of-implementing-factories)
May be this piece of code could help you and give ideas of how powerfull can be working with function pointers.
#include <stdio.h>
#include <stdlib.h>
#include <map>
// Define the func ptrs
typedef void (*TFunc)(const char *, int);
typedef int (*TFunc2)(int);
int return_value(int i)
{
return i * 5;
}
void a( const char *name, int i )
{
printf ("a->%s %d\n\n", name, i);
}
void b( const char *name, int i)
{
printf ("b->%s %d\n\n", name, i);
}
struct test
{
const char *name;
int i;
TFunc func;
};
static test test_array[2] =
{
{ "a", 0, a },
{ "b", 1, b },
};
int main(int argc, char **argv, char** envp)
{
// Check the simple case, pointer to a function
TFunc fnc = a;
TFunc2 fnc2 = return_value;
fnc("blabla", 5);
fnc = b;
fnc("hello!", 55);
printf ("%d\n\n",fnc2(5));
//Check arrays of structs when there is a pointer to a fnc
test_array[0].func(test_array[0].name, test_array[0].i);
test_array[1].func(test_array[1].name, test_array[1].i);
//Handle a map of functions( This could be a little implementation of a factory )
typedef std::map<int, TFunc > myMap;
myMap lMap;
lMap.insert(std::make_pair(5, a));
lMap.insert(std::make_pair(2, b));
if( lMap.find( 5 ) != lMap.end() )
{
lMap[5]("hello map 5", 1);
}
myMap::iterator lItFind = lMap.find(2);
if( lItFind != lMap.end() )
{
lItFind->second("hello map 2", 2);
}
return(0);
}
I hope that this helps you.
You should remove extra parentheses, this is correct version:
int* (*function)(int, int (*k)(int *));
explanation (using right-left rule):
int* (*fn)(int, int (*k)(int *));
fn : fn is a
(*fn) : pointer
(*fn)(int, int (*k)(int *)) : to a function taking as arguments
- an int and
- function pointer
which takes a pointer to int
and returns int
int* (*fn)(int, int (*k)(int *)) : and returns a pointer to int
below is a short example on how to use it, also you ask for How to define pointer to pointer to function so below this is also included.
http://coliru.stacked-crooked.com/a/d05200cf5f6397b8
#include <iostream>
int bar(int*) {
std::cout << "inside bar\n";
return 0;
}
int* foo(int, int (*k)(int *)) {
std::cout << "inside foo\n";
k(nullptr);
return nullptr;
}
int main() {
int* (*function)(int, int (*k)(int *));
function = foo;
function(0, bar);
// Now, as you asked for, a pointer to pointer to above function
decltype(function) *pff;
pff = &function;
(*pff)(0, bar);
}
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..
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;
}
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