What does this code mean?
char code[] = "bytecode will go here!";
int main(int argc, char **argv) {
int (*func)(); /* This is pointer to function */
func = (int (*)())code; /* What does this line mean? */
(int)(*func)(); /* Calling function by pointer */
}
func = (int (*)()) code;
code, being an array, is implicitly converted to a pointer to its first element (it decays to such a pointer). This pointer is then cast to a pointer to a function.
This cast causes undefined behaviour. But "most of the time", it will probably result in a function pointer pointing to the address of the array. When you call it, then control jumps to this array. If it contains string data, you'll most likely get an invalid opcode or a segmentation fault. But if that array contains some user input a malicious user could've put (compiled) code into it, doing all sorts of funny (or less funny) stuff.
As an example, consider the above code running in some sort of server, being fed user input over some website. Then one could replace the program with, for example /bin/sh and thus gain shell access on that server.
What you're seeing there is an example of type punning.
void print_hello()
{
printf("hello");
}
int main()
{
void (*hello_func_ptr)() = &print_hello;
//we convert what the function points to to a string of "byte code"
char *func_byte_code = (char *)hello_func_ptr;
// prints out byte code of the function
printf(func_byte_code);
// we cast the string byte code to a function pointer
void (*func_from_byte_code)() = (void (*)())func_byte_code;
// we call the function we got from casting the byte code to a function pointer
(*func_from_byte_code)(); // prints "hello"!
return 0;
}
What your function does is taking the byte code string and convert it back to a function pointer like we've done above. You can then call the function by dereferencing the pointer and calling it by adding the parentheses and any parameters the function takes.
Now of course, you shouldn't need to do things like that in regular programming but seldom in peculiar cases.
This is a sample of shell code.
here:https://en.wikipedia.org/wiki/Shellcode
func = (int (*)()) code; /* What does this line mean? */
func is a function point,it point to the address of "code array".
when the func be called,program will be jump to the address of array.
Related
So, I am just trying to wrap my head around "pointer function that returns a pointer to an array"... but to start off slowly, I had to understand this:
void Print(const char c){
printf("\nPrint: %c\n", c);
}
int main () {
void (*FunctionPointer)(const char);
FunctionPointer = &Print;
FunctionPointer('a');
}
Which I do - pretty easy to guess what is going on... FunctionPointer just points to the location where the Print function "resides". Instead of jumping to a specific memory address (stored on a register) of a specific function, I can now be more flexible and point to any function that I want to access.
But I am stuck with the following...
int main () {
int (*FunctionPointer())[];
}
Now it seems that the function that is pointed by FunctionPointer, can in fact return a pointer to an array of type int. The compiler accepts the second line - so far so good - and I also understand the concept... but I am getting stuck regarding the implementation.
FunctionPointer needs - once again, to point to a function. That function can indeed return a pointer that points to an array of type int... soooooo:
int *Array(){
int ar[2] = {5,6};
return ar;
}
int main () {
int (*FunctionPointer())[];
FunctionPointer = &Array;
}
However, the last piece of code is just not accepted by the compiler.... So, what gives?
With
int (*FunctionPointer())[];
you've declared FunctionPointer as a function returning a pointer to an array of int -- not a function pointer. You want
int *(*FunctionPointer)();
If you use [] here, you'll get an error, as functions can't return arrays -- arrays are not first class types -- and unlike with function parameters, arrays will not be silently converted to pointers when used as the return value of a function type. With that, you'll still get the warning
t.c:3:12: warning: function returns address of local variable [-Wreturn-local-addr]
return ar;
^~
which is pretty self-explanatory
You have declared the array of function pointers. Arrays can't be assignable. Functions can't return arrays. You might wish
int* (*FunctionPointer)();
FunctionPointer = &Array;
Function pointers are much easier when you use typedefs. You can simply use the same notation as "normal" data pointers.
// func is a function type. It has one parater and returns pointer to int
typedef int *func(const char);
// funcptr is a pointer to func
func *funcptr;
I am trying to build a parser to a given input, there are 8 possible commands. So I figured that instead of using the ugly technique of a case switch block like that:
switch(command)
case cmd1:
.... /*call a function that do cmd1*/
case cmd2
..../*call a function that do cmd2*/
I will define in a header an array of structs, each one contains the name of the function, and a pointer to a function:
typedef struct command_info
{
char *name;
void (*func)(int)
};
command_info command_table[] = {{"func1", &func1}, {"func2", &func2} }
So that I can switch to the more elegant:
int i;
for(i = 0; i < COMMAND_TABLE_LENGTH; i++)
if(!strcmp(command_table[i].name, command))
command_table[i].func(2);
My only problem is, that the functions have different parameters (all return void). This is not a problem for me since I can check if the function is func1 or func2 search for one int argument for example, and if it is func3 or func4 search for two (still more compact than case switch). But the function pointer only points to a function with a certain type and amount of arguments. How can I make a universal pointer that can point to any function?
But the function pointer only points to a function with a certain type and amount of arguments.
How can I make a universal pointer that can point to any function?
In OP's limited case, use void (*func)().
Any function pointer can be converted with a type cast to another function pointer and retain an equivalent function address. #Jonathan Leffler
int (*foo)(int) = (int (*)(int)) sqrt;
double (*sq)(double) = (double (*)(double)) foo;
printf("%f\n", sq(2)); // prints 1.414214
A function pointer need not provide a function parameter signature.
// No parameter info
// vv
int (*foo)() = (int (*)()) sqrt;
OP has "functions have different parameters (all return void)", so in OP's case code could use a limited universal function pointer of void (*func)() and lose parameter checking.
typedef struct {
char *name; // suggest const char *name
void (*func)(); // no parameter info nor checking
} command_info;
char buf[100];
// void setbuf(FILE * restrict stream, char * restrict buf);
command_info fred = { "my_setbuf", setbuf };
// Both compile, 2nd is UB.
fred.func(stdin, buf); // No parameter checking.
fred.func(0); // No parameter checking.
Code also incurs a subtle issue when calling .funf(): the parameters ranking lower than int/unsigned are promoted as well as float parameters before passed to the function. Best to make certain the parameters are not char, float, short, _Bool etc. to avoid compatible signature issues.
void * is a universal object pointer. It may be insufficient to encode a function pointer. So it is not a portable candidate. It is not uncommon for the size of a function pointer to be wider than sizeof(void*).
I have a function that is supposed to read (in a very bad way) a file. I expect it to modify a struct that I pass as a parameter to store the things that it has to read. But when I call it, it throws a segmentation fault. I have a print as the first thing the function does, and it doesn't do it. So I guess I have a problem with the declaration of the function or something. I can't figure it out.
int main(int argc, char **argv){
//some parser here
struct client_config *config;
read_software_config_file(*config); //I also passed it as non pointer and & but nothing worked.
}
void read_software_config_file(struct client_config config){
printf("Hello"); //it breaks here
}
As someone pointed out I did this:
struct client_config config;
read_software_config_file(&config);
But it still shows me segmentation fault.
Here is a working example:
#include <stdio.h>
struct client_config
{
int data;
};
void read_software_config_file(struct client_config *config); // Forward Declaration
int main(int argc, char **argv)
{
struct client_config config; // Memory on stack. Use malloc/calloc for heap
config.data = 10; // Init data
read_software_config_file(&config);
printf("config.data = %d\n", config.data);
return 0;
}
void read_software_config_file(struct client_config *config)
{
printf("Hello\n");
config->data = 12;
}
I would generally advise to compile with -Wall -Wextra -pedantic to catch errors early.
You have to forward declare the function read_software_config_file (or include a header etc.) s.t. the compiler knows the signature when you call it in main.
As said in the comments you should take a pointer to the struct, s.t. it can be modified.
The output after running main is:
Hello
config.data = 12
When you declare any variable, pointer or not, without initializing it, it gets whatever is in memory as its current value. Some higher level languages may implicitly initialize all new values with "default" variables. You may have gotten used to this from previous programming experience; this is not the case in C.
If you use the * dereference operator on an uninitialized pointer, you are dereferencing whatever address is represented by the current value of the pointer, which is undefined behavior, and almost certainly going to cause an access violation.
You need to initialize your pointer to point to something; either an existing struct client_config, or new heap memory allocated with malloc or calloc.
Also, if your function really is meant to take a pointer to a struct client_config, the parameter should have a * operator on it as well.
This is the question i am working on.
"A simple encryption scheme named "rotate13" for encrypting text is to convert each letter (a…z or A...Z) to another letter by counting forward 13 letters, looping around from 'z' to 'a' or 'Z' back to 'A' if necessary.
Write a function named rotate13 which takes a single null-terminated string as a parameter
and converts it to its rotate13 equivalent. The function should modify the string directly, and it
should not return anything. Remember, only letters should change; all other characters remain
the same. You may assume that ctype.h is correctly included at the top of your program so
that you can use any functions within the library if you wish. "
And this is the error i keep getting
"error C2664: 'rotate13' : cannot convert parameter 1 from 'char (*)[10]' to 'char *[]'"
Thanks for the help. It will help me in my revisions for finals.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int rotate13(char *array[]);
int size=10;
int main()
{
char arr[10];
printf("Please enter the letters you wish to encrypt: ");
scanf("%s",&arr);
printf("%s",arr);
rotate13(&arr);
system ("pause");
return 0;
}
int rotate13(char *array[])
{
int pointer;
while(*array[pointer]!='\0')
{
if(isupper(*array[pointer])!=0)
{
if(*array[pointer]<'N')
*array[pointer]=*array[pointer]+13;
else
*array[pointer]=*array[pointer]-13;
}
else
{
if(*array[pointer]<'n')
*array[pointer]=*array[pointer]+13;
else
*array[pointer]=*array[pointer]-13;
}
pointer++;
}
printf("%s", *array);
return 0;
}
Remove & from scanf("%s",&arr);
scanf("%s",arr);
rotate13 is expecting an argument of type char ** but, by passing &arr you are passing it an argument of type int (*)[10]. Passing arr to rotate13 will solve your problem.
rotate13(arr);
You want to pass a string as the parameter of rotate13, so use either
int rotate13(char *array);
or
int rotate13(char array[]);
and pass arr like rotate13(arr). the same for scanf("%s",arr);
And inside the function rotate13, pointer is an int(bad variable name) that isn't initialized. To access the characters, use array[pointer], not *arr[pointer].
The function should look like this:
int rotate13(char array[])
{
int n;
while(array[n]!='\0')
{
Use rotate13(arr); instead of rotate13(&arr); and parameter should be char [] instead of char *[]
rotate13(&arr); sends the address of the array to the function which causes the parameter mismatch
As other answers have said, you're better of with int rotate13(char array[]). To understand the context, you should read this wonderful page: http://c-faq.com/aryptr/
Basically, passing a pointer to an array is redundant here, because in C when you pass an array to a function, what's actually passed is a pointer to its first element. Arrays are inherently passed by reference.
Some things need to be explained. "string" in C is the address of a character buffer.
Since the identifier arr in char arr[10]; degrades to a pointer to the first element of the array, So you don't need to specify a pointer (i.e &) to the string in the argument to scanf.
By passing &arr in your scanf as scanf("%s",&arr); the pointer passed to scanf is now a doubly-indirect pointer (it is a pointer to a pointer to the beginning of the buffer) and will likely cause the program to crash or other bad behaviour.
The strings in c, dont require &array as they implicitly pass address of the first element of the character array
So your two statments scanf("%s",&arr) should be simply scanf("%s",arr) and rotate13(&arr) should be rotate13(arr). notice that address of the first element are implicitly passed in the function calls.
Your function rotate13(char *array[ ]) is completely wrong way of doing it
char arr[10] -> can hold single string ( simply an array )
char *array[] -> can hold multiple strings ( also called array of pointers)
the formal parameter should be rotate13(char array[]) or rotate13(char *array).
After seeing your code I believe your not changing the contents of arr so you require a call by value instead of a call by address
char array[] - > call by value , char *array -> call by address
Your variable int pointer is not initialized before its use, Its dangerous. First initialize is to zero.
Change all the occurences of *array[pointer] to array[pointer]
If your wishing to change the contents of arr use call by address just change rotate13(char array[]) to rotate13(char *array) and Dont forget to initialize pointer variable to zero .
I've just started to work with C, and never had to deal with pointers in previous languages I used, so I was wondering what method is better if just modifying a string.
pointerstring vs normal.
Also if you want to provide more information about when to use pointers that would be great. I was shocked when I found out that the function "normal" would even modify the string passed, and update in the main function without a return value.
#include <stdio.h>
void pointerstring(char *s);
void normal(char s[]);
int main() {
char string[20];
pointerstring(string);
printf("\nPointer: %s\n",string);
normal(string);
printf("Normal: %s\n",string);
}
void pointerstring(char *s) {
sprintf(s,"Hello");
}
void normal(char s[]) {
sprintf(s,"World");
}
Output:
Pointer: Hello
Normal: World
In a function declaration, char [] and char * are equivalent. Function parameters with outer-level array type are transformed to the equivalent pointer type; this affects calling code and the function body itself.
Because of this, it's better to use the char * syntax as otherwise you could be confused and attempt e.g. to take the sizeof of an outer-level fixed-length array type parameter:
void foo(char s[10]) {
printf("%z\n", sizeof(s)); // prints 4 (or 8), not 10
}
When you pass a parameter declared as a pointer to a function (and the pointer parameter is not declared const), you are explicitly giving the function permission to modify the object or array the pointer points to.
One of the problems in C is that arrays are second-class citizens. In almost all useful circumstances, among them when passing them to a function, arrays decay to pointers (thereby losing their size information).
Therefore, it makes no difference whether you take an array as T* arg or T arg[] — the latter is a mere synonym for the former. Both are pointers to the first character of the string variable defined in main(), so both have access to the original data and can modify it.
Note: C always passes arguments per copy. This is also true in this case. However, when you pass a pointer (or an array decaying to a pointer), what is copied is the address, so that the object referred to is accessible through two different copies of its address.
With pointer Vs Without pointer
1) We can directly pass a local variable reference(address) to the new function to process and update the values, instead of sending the values to the function and returning the values from the function.
With pointers
...
int a = 10;
func(&a);
...
void func(int *x);
{
//do something with the value *x(10)
*x = 5;
}
Without pointers
...
int a = 10;
a = func(a);
...
int func(int x);
{
//do something with the value x(10)
x = 5;
return x;
}
2) Global or static variable has life time scope and local variable has scope only to a function. If we want to create a user defined scope variable means pointer is requried. That means if we want to create a variable which should have scope in some n number of functions means, create a dynamic memory for that variable in first function and pass it to all the function, finally free the memory in nth function.
3) If we want to keep member function also in sturucture along with member variables then we can go for function pointers.
struct data;
struct data
{
int no1, no2, ans;
void (*pfAdd)(struct data*);
void (*pfSub)(struct data*);
void (*pfMul)(struct data*);
void (*pfDiv)(struct data*);
};
void add(struct data* x)
{
x.ans = x.no1, x.no2;
}
...
struct data a;
a.no1 = 10;
a.no1 = 5;
a.pfAdd = add;
...
a.pfAdd(&a);
printf("Addition is %d\n", a.ans);
...
4) Consider a structure data which size s is very big. If we want to send a variable of this structure to another function better to send as reference. Because this will reduce the activation record(in stack) size created for the new function.
With Pointers - It will requires only 4bytes (in 32 bit m/c) or 8 bytes (in 64 bit m/c) in activation record(in stack) of function func
...
struct data a;
func(&a);
...
Without Pointers - It will requires s bytes in activation record(in stack) of function func. Conside the s is sizeof(struct data) which is very big value.
...
struct data a;
func(a);
...
5) We can change a value of a constant variable with pointers.
...
const int a = 10;
int *p = NULL;
p = (int *)&a;
*p = 5;
printf("%d", a); //This will print 5
...
in addition to the other answers, my comment about "string"-manipulating functions (string = zero terminated char array): always return the string parameter as a return value.
So you can use the function procedural or functional, like in printf("Dear %s, ", normal(buf));