C language pointer array in Struct - arrays

Code:
#include <stdio.h>
#include <stdlib.h>
typedef struct{
int *arr;
}example;
void Create(example var){
var.arr = (int *)malloc(sizeof(int)*2);
}
int main(){
example var1, var2;
var1.arr = (int *)malloc(sizeof(int)*2);
var1.arr[0] = 11;
var1.arr[1] = 22;
printf("%d %d\n",var1.arr[0],var1.arr[1]);
Create(var2);
var2.arr[0] = 111;
var2.arr[1] = 222;
printf("%d %d\n",var2.arr[0],var2.arr[1]);
return 0;
}
OUT:
11 22
Segmentation Fault
My code is as above. I don't get any error when I do it manually as in var1. But if I do it inside a function as in var2, I get an error. How can I fix this. I want to do it inside the function.
EDIT:Thank you for your answers. It worked

The problem is that Create() is making a COPY of your struct. The original struct is unchanged.
If your program was C++, you'd want to pass a "reference".
Here, you want to pass a pointer:
void Create(example * mystruct){
mystruct->arr = (int *)malloc(sizeof(int)*2);
}
int main(){
example var1, var2;
...
Create(&var2);

you have to pass reference of var2:
Create(&var2);

The function parameter
void Create(example var){
var.arr = (int *)malloc(sizeof(int)*2);
}
is its local variable that is initialized by the passed argument and is not alive after exiting the function.
That is this call
Create(var2);
did not change the variable var2 declared in main.
As a result in these statements
var2.arr[0] = 111;
var2.arr[1] = 222;
there is used uninitialized pointer arr that has an indeterminate value that invokes undefined behavior.
You need to pass the variable by reference to the function. For example
void Create(example *var){
var->arr = (int *)malloc(sizeof(int)*2);
}
and the function is called like
Create( &var2 );

Related

How to run a function using a function pointer that located in a struct? (C)

I want to create an array of structs based on one struct definition, and initialize each one with a different int value.
Then, I want to print this value, using a function pointer that points to a print function.
Define a struct (includes an int and a function pointer).
create an array of 10 structs of the same definition.
set different values for each one of them.
send this value for a function that is pointed to by a function
pointer that is also located in the struct
This is my code:
#include <stdio.h>
#include <stdlib.h>
#define ARRAY_SIZE 10
void Print(int num);
typedef struct print_me
{
int x;
void (*Print)(int x);
};
struct print_me my_prints[ARRAY_SIZE];
int main()
{
size_t i = 0;
for (i = 0; i < ARRAY_SIZE; ++i)
{
my_prints[i].x = i;
my_prints[i].Print(my_prints[i].x);
}
return 0;
}
void Print(int num)
{
printf("%d\n",num);
}
I'm still learning the ideas of function pointer and structs , so I'll be glad to get some tips and suggestions that will help me to understand my mistakes here.
Thanks.
For starters there is no any sense to use the typedef specifier in this declaration
typedef struct print_me
{
int x;
void (*Print)(int x);
};
without specifying a typedef name. You could write for example
typedef struct print_me
{
int x;
void (*Print)(int x);
} print_me;
In the for loop you need to initialize the data member Print with the address of the function Print. For example
for (i = 0; i < ARRAY_SIZE; ++i)
{
my_prints[i].x = i;
my_prints[i].Print = Print;
}
then in a second for loop you could call the function like
for (i = 0; i < ARRAY_SIZE; ++i)
{
my_prints[i].Print( my_prints[i].x );
}
As with usual pointers, you have to set a pointer value before you can use it. So that it points somewhere.
Add:
my_prints[i].Print = &Print;
// or, it means the same, & is optional
// my_prints[i].Print = Print;
my_prints[i].Print(my_prints[i].x); // now ok
before calling my_prints[i].Print() so that the pointer will point to function Print before calling it.
Side note with a fun fact: because of the strange C rules, dereferencing the function pointer is not needed, and you can even like "dereference" the function pointer multiple times, like (****my_prints[i].Print)(). See ex this question.

is it possible? passing address of local static value to main pointer?

#include<stdio.h>
void f(int *p) {
static int data = 5;
p=&data;
}
int main(void) {
int *ip=NULL;
f(ip);
printf("%d\n", *ip);
return 0;
}
if it is possible.
what is cause error?
how can I fix the code?
In this way you end up changing the value of a local pointer, you need to pass a pointer to pointer (&) from main and use the dereference operator (*) in the function:
#include <stdio.h>
void f(int **p) {
static int data = 5;
*p = &data;
}
int main(void) {
int *ip = NULL;
f(&ip);
printf("%d\n", *ip);
return 0;
}
But usually we prefer to work with the same level of indirection returning the address from the function, this is easier to read (at least for me):
#include <stdio.h>
int *f(void) {
static int data = 5;
return &data;
}
int main(void) {
int *ip = f();
printf("%d\n", *ip);
return 0;
}
You have to pass a pointer to the pointer to change the value of the actual pointer:
void some_fun(int **p)
{
static int i = 10;
*p = &i;
}
That being said, it is not necessarily advisable to do that. The only direct use I could think of is to delay the execution of the initialization of a global until its first use.

Defining a program local pointer of a structure

my question deals with creating variables that are visible throughout the program file. In other words, a file-local variable.
Consider this example
#include <stdio.h>
struct foo
{
char s[] = "HELLO";
int n = 5;
};
struct foo *a;
int main()
{
puts("Dummy outputs!\n");
printf("%s\n",a->s);
printf("%d\n",a->n);
return 0;
}
Now, this code snippet won't run.
Why?
Because the structure pointed to be pointer variable a will not get allocated as the statement never executed.
Now, how do you get it allocated without changing the scope of this variable a?
#include <stdio.h>
struct foo {
char const *s;
int n;
};
/* static for file-local */
static struct foo a = { "HELLO" , 5 };
int main(void) {
printf("%s\n", a.s);
printf("%d\n", a.n);
return 0;
}
Now, how do you get it allocated without changing the scope of this variable a?
I am sure there a lot of ways to solve your problem. Here's my suggestion.
Change the definition of struct foo to contain a fixed number of characters in s.
Create a as an object instead of a pointer. Initialize it with the necessary values.
Make a a static variable so its use is limited to the file only.
Use the object a instead of the pointer a in rest of the file.
#include <stdio.h>
struct foo
{
char s[20];
int n;
};
static struct foo a = {"HELLO", 20};
int main()
{
puts("Dummy outputs!\n");
printf("%s\n",a.s);
printf("%d\n",a.n);
return 0;
}
This:
struct foo
{
char s[] = "HELLO";
int n = 5;
};
Is not valid C code. You first declare the type:
struct foo
{
char s[10];
int n;
};
Then define a variable of that type:
static struct foo a = { "HELLO", 5 };
The static keyword allows this variable to have file local scope.
You can now use it like this:
static struct foo a = { "HELLO", 5 };
void other()
{
puts("Dummy outputs!\n");
printf("%s\n",a.s);
printf("%d\n",a.n);
}
int main()
{
puts("Dummy outputs!\n");
printf("%s\n",a.s);
printf("%d\n",a.n);
other();
return 0;
}
Note that a is accessible from both functions. It will not however be viewable from functions defined in other files because it is declared as static.
As for using a pointer vs the struct directly, you can take the address of this structure at any time you need to use it in that way:
some_function(&a);
well, i need to use a pointer instead of a structure directly
Try this:
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
struct foo{
char s[20];
int n;
};
int main(void){
struct foo *a;
a = malloc(sizeof(struct foo));
puts("Dummy outputs!\n");
strcpy(a->s, "HELLO");
a->n = 5;
printf("%s\n",a->s);
printf("%d\n",a->n);
free(a);
return 0;
}
Output:
Dummy outputs!
HELLO
5

Modifying an index in an array, using pointers

I'm attempting to modify an array using only pointers.
void modify(){
int *ptr = &b[2];
*ptr = 90;
}
//I have my main function
void main() {
int b[15];
//fill the array with values using loop..skipping this part
modify();
}
The error that its giving me is : error: use of undeclared identifier 'b'
Can anyone give me some insight as to why the compiler does not recognize the array b?
b is declared as a local variable in main(), and thus can only be accessed by main(). To make b visible to other functions, make it a global variable by declaring it outside of any functions:
int b[3];
void modify(){
int *ptr = &b[2];
*ptr = 90;
}
int main(void) { //This is one of the standard signatures of main
//Fill the array with values using a loop
modify();
return 0; //main returns an int
}

How can I use variable p to declare a new pointer to function using following

I have p like:
typedef int (*p)();
Let's say the function to which I want to declare a pointer is int foo().
I wanna declare a new pointer to function foo using variable p to make use of typedef statement like:
typedef int emp[10];
emp p;// so now p is an array of size 10 of type int
p is:
typedef int (*p) ();
foo() is:
int foo(){
}
p type variable is f:
p f = &foo;
how to call using pointer:
(*f)();
Example code:
#include<stdio.h>
int foo(){
printf("\n In FOO\n");
return 4;
}
typedef int(*p)();
int main(){
p f = &foo;
int i = (*f)();
printf("\n i = %d\n", i);
return 1;
}
you can find it is working on codepad.
note: you can simply assign like p f = foo; and call like f() the second form you can find here on codepad
Edit: As #Akash commented:
it compiles and runs like:
~$ gcc x.c -Wall
~$ ./a.out
In FOO
i = 4
Here is a project to help explain the usefulness of function pointers.
int foo()
{
// do something
}
typedef int (*p)();
int main( int argc, char** argv )
{
int result;
p funcPtr = foo;
result = funcPtr();
return 0;
}
With a typedef:
typdef int (*FunctionPtr)();
int foo()
{
return 4; // chosen by fair dice roll, should be random
}
FunctionPtr fptr = foo; // or &foo
Without a typedef:
int (*fptr)() = foo; // or &foo
From this post: convert C function array to c++ functions pointer array?
#include <stdio.h>
void f1() {printf("helo\n");}
void f2() {printf("world\n");}
typedef struct func
{
void (*f)();
}func;
int main()
{
func a[] = {{f1}, {f2}};
a[0].f();
return 0;
}

Resources