Segmentation Fault in function pointer [closed] - c

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 3 years ago.
Improve this question
I have an example code as below, because I'm not familiar with the function pointer so that I cannot find out what is happening at
ret = (p_local->str)(10,b_in); (segmentation fault)
#include "stdio.h"
typedef int (*check)(const int a, char * const b[]);
typedef struct ST_T_COMMAND
{
char *chuoi;
check str;
} T_COMMAND;
const T_COMMAND *p_global;
int main()
{
int ret;
const T_COMMAND *p_local;
char *b_in[] = {"1234", "abchd"};
T_COMMAND str_new;
p_global = &str_new;
str_new.chuoi = "1234";
p_local = p_global;
if(strcmp(p_local->chuoi, b_in[0]) == 0)
{
ret = (p_local->str)(10, b_in);
printf("ret = %d\n", ret);
}
else
{
printf("else\n");
}
return 0;
}
I want to pass that segmentation fault. And please tell me what is wrong with my code

Here
typedef int (*check)(const int a, char * const b[]);
you have declared the function pointer i.e check is the function pointer name, it can points to any function whose input argument are int and char* const [] type & which returns int type.
And here
ret = (p_local->str)(10, b_in); /* calling via function pointer */
you are trying to call via function pointer but you haven't initialized function pointer anywhere. You need to initialize function pointer first before calling it.
Also
const T_COMMAND *p_local; /* initialize it here itself */
above syntax means where p_local points that is constant i.e when you will do like
p_local->str = funHandler;
as I did below, compiler will not allow it to modify.
Same with p_global, if you make this as const earlier, you can't do like
const T_COMMAND *p_global;
p_local = p_global; /* not possible due to above const declaration of p_global */
Try this version:
#include <stdio.h>
#include <string.h>
typedef int (*check)(const int a, char * const b[]);
typedef struct ST_T_COMMAND
{
char *chuoi;
check str;
}T_COMMAND;
T_COMMAND *p_global; /* removed const */
int funHandler(int num, char* const buf[10])
{
printf("in funHandler() %d %s\n", num, buf[0]);
return num;
}
int main(void)
{
int ret;
T_COMMAND *p_local; /* removed const */
char * b_in[] = {"1234","abchd"};
T_COMMAND str_new;
p_global = &str_new;
str_new.chuoi = "1234";
p_local = p_global;
if(strcmp(p_local->chuoi,b_in[0]) == 0)
{
p_local->str = funHandler; /* initialize function pointer, you missed this */
ret = (p_local->str)(10,b_in);
printf("ret = %d\n",ret);
}
else
{
printf("else\n");
}
return 0;
}

ret = (p_local->str)(10,b_in);
You are calling the function p_local->str without initializing it first.
You need to set a value to plocal->str (or any of the equivalent values in your program i.e. p_global, str_new)
This value should be a function that you have defined elsewhere which matches the type of the function pointer i.e. parameters of const int a and char * const b[]

Related

Problem with calling a function via a function pointer [duplicate]

This question already has answers here:
How can I call a function using a function pointer?
(16 answers)
Closed 1 year ago.
I have a struct with a function pointer, that is intended for pointing to the bar() function, but i have no clue how to call the function that's being pointed on:
#include <stdlib.h>
typedef struct Foo
{
int (*func_ptr)(const char *, const char *);
} Foo;
int bar(const char *a, const char *b)
{
return 3;
}
int main(void)
{
Foo *foo = (Foo *)malloc(sizeof(Foo));
foo->func_ptr = &bar;
//how do i call the function?
return 0;
}
Imagine your const char *a is "hello" and const char *b is "there", then you can use any of the following forms to call the function by its pointer:
(foo->func_ptr)("hello", "there");
(*foo->func_ptr)("hello", "there");
foo->func_ptr("hello", "there");

Realloc keeps returning NULL if reallocating structs [duplicate]

This question already has answers here:
Assignment of function parameter has no effect outside the function
(2 answers)
How do I modify a pointer that has been passed into a function in C?
(7 answers)
Closed 2 years ago.
Don't mind my code writing style. I specifically created this for testing purposes...
Now to the problem:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define EMB 31
#define NAME_MAX 50
struct TRIP {
char TRIP_NAME[EMB];
int TRIP_TIME;
};
struct DATE {
int day;
int month;
int year;
};
struct TRIP_INFORMATION {
char TRIP_NUMBER[EMB];
char EMBARKATION_POINT[EMB];
char SPECIFIC_DROPOFFPOINT[EMB];
char EXIT_DROPOFFPOINT[EMB];
struct DATE TRIP_DATE;
struct TRIP SPECIFIC_TRIP;
};
struct EMBARKATION_CARD{
//struct DATE TRIP_DATE;
char NAME[NAME_MAX];
int ID_NUMBER;
int PRIORITY_NUMBER;
//int TRIP_TIME;
//char EMBARKATION_POINT[EMB];
//char DROPOFFPOINT[EMB];
struct TRIP_INFORMATION TRIP_INFORMATION;
};
This is for the reference of declaration.
int BeginEmbarkationProcess(int *PASSENGER_COUNT, struct EMBARKATION_CARD * PASSENGER_TO_SAVE, int curr_day, int curr_month, int curr_year){
//struct EMBARKATION_CARD * P;
if(*PASSENGER_COUNT>1){
PASSENGER_TO_SAVE = realloc(PASSENGER_TO_SAVE, *PASSENGER_COUNT * sizeof(struct EMBARKATION_CARD));
if(PASSENGER_TO_SAVE == NULL){
puts("PASSENGER_TO_SAVE VARIABLE = HAS NOT ALLOCATED MEMORY");
return -1;
}
}
if(PASSENGER_TO_SAVE==NULL){
puts("PASSENGER TO SAVE POINTER HAS UNABLE TO ALLOCATE MEMORY");
return -1;
}
int x = 0;
for(x=0;x<*PASSENGER_COUNT;x++){
((PASSENGER_TO_SAVE+x))->ID_NUMBER = (x+1)*30;
((PASSENGER_TO_SAVE+x))->PRIORITY_NUMBER = (x+1)*17;
}
for(x=0;x<*PASSENGER_COUNT;x++){
printf("%d %d\n", (PASSENGER_TO_SAVE+x)->ID_NUMBER , (PASSENGER_TO_SAVE+x)->PRIORITY_NUMBER);
}
*PASSENGER_COUNT = *PASSENGER_COUNT + 1;
int r;
printf("ENTER -1 TO TERMINATE THIS LOOP\n");
scanf("%d", &r);
return r;
}
int main(){
//doIt();
struct EMBARKATION_CARD* E = malloc(sizeof(struct EMBARKATION_CARD));
int ct = 1;
int s = BeginEmbarkationProcess(&ct, E, 3, 3, 2020);
while(s!=-1){
s = BeginEmbarkationProcess(&ct, E, 3, 3, 2020);
}
return s;
}
Since I copy pasted this (and removed some commented out lines but eventually got tired of it), this copy pasted code might have some syntax error. Ignore those syntax error please.
The issue is that realloc WILL keep returning NULL.
This prevents me from readjusting it.
Can someone tell me what the hell is going on.
I know I may have made some errors here but I want to learn about it.
Yes I am just a student learning C language.

Segmentation fault while referencing and adding values to a structure

Okay, so the problem concerns adding values through function to structure. Honestly, I couldn't solve the problem (spent a lot of time trying), so I am asking for your help. While executing the program, I get a segmentation fault. It occurs while using the variables from stack stos.
typedef struct e {
int zaglebienie[100];
char *nazwa_funkcji[100];
int poz;
} *stack;
void put_on_fun_stack(int par_level, char *funame, stack stos) {
int i = stos->poz;
stos->zaglebienie[i] = par_level;
char *funkcja = strdup(funame);
stos->nazwa_funkcji[i] = funkcja;
stos->poz++;
}
int main() {
char *p = "makro";
stack stos;
stos->zaglebienie[0] = 0;
put_on_fun_stack(1, p, stos);
return 0;
}
You're declaring a pointer to stack but you're not allocating any memory to it.
And as already mentioned in the comments, using typedef with with a pointer will unnecessarily complicate your life.
So I suggest you create the struct stack and then in main declare a pointer to stack and allocate memory for it, somewhat like this:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct e {
int zaglebienie[100];
char *nazwa_funkcji[100];
int poz;
} stack;
void put_on_fun_stack(int par_level, char *funame, stack *stos)
{
int i = stos->poz;
stos->zaglebienie[i] = par_level;
char *funkcja = strdup(funame);
stos->nazwa_funkcji[i] = funkcja;
stos->poz++;
}
int main(void)
{
char *p = "makro";
// calloc to initialize stos variables to 0
stack *stos = calloc(sizeof(stack), 1);
printf("stos->poz before: %d\n", stos->poz);
put_on_fun_stack(1, p, stos);
printf("stos->poz after: %d\n", stos->poz);
printf("stos->nazwa_funkcji[0]: %s\n", stos->nazwa_funkcji[0]);
free(stos->nazwa_funkcji[0]);
free(stos);
return 0;
}
Output:
stos->poz before: 0
stos->poz after: 1
stos->nazwa_funkcji[0]: makro

Equivalent of std::bind in C by hacking the stack

After some research I didn't find a good way to implement the std::bind in C.
I build a small program that implements an equivalent of std::bind in C by hacking the stack.
There's two functions I will try to bind to function with pre-defined arguments.
My problem is this code is only working under Windows. Under Linux, this is a mess. I this the problem is my knowledge of the stack and the way that arguments are store in memory.
Thanks,
Please, find below the code I made:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
The two functions I want to bind :
void test1 (int nombre, char t, int nombre2)
{
printf ("test 1 : %d%c%d\n", nombre, t, nombre2);
}
void test2 (char t, int nombre, int nombre2)
{
printf ("test 2 : %c%d%d\n", t, nombre, nombre2);
}
Two struct that will store the argument of each function (order of fields is important).
typedef struct {
int nombre;
char t;
int nombre2;
} struct1;
typedef struct {
char t;
int nombre;
int nombre2;
} struct2;
This "fake" struct will be use to write on the stack by dereferencing a structvoid* variable.
// Size must be bigger than every struct*
typedef struct {
int i[10];
} structvoid;
The main function.
int main(int argc, char** argv) {
// Variables to store the two functions and their arguments.
void * functions[2];
structvoid * data[2];
void *func1 = (void *)&test1;
void *func2 = (void *)&test2;
void (*functionPtrc)(structurevoid);
// Definition of the argument of the first function test1
struct1 data1;
data1.nombre = 15;
data1.t = 'c';
data1.nombre2 = 30;
// and storing data.
void *datac = malloc (sizeof (structvoid));
memcpy(datac, &data1, sizeof (struct1));
data[0] = (structvoid*)datac;
functions[0] = func1;
// Same thing with function 2.
struct2 data2;
data2.t = 'a';
data2.nombre = 5;
data2.nombre2 = 10;
datac = malloc (sizeof (structvoid));
memcpy(datac, &data2, sizeof (struct2));
data[1] = (structvoid*)datac;
functions[1] = func2;
// Get the pointer to the first function (test1);
functionPtrc = functions[0];
// All the hack is here. By dereferencing the data, this will write on the stack all arguments need by the test1 function.
functionPtrc(*data[0]);
functionPtrc = functions[1];
functionPtrc(*data[1]);
// To check the result.
test1 (data1.nombre, data1.t, data1.nombre2);
test2 (data2.t, data2.nombre, data2.nombre2);
return 0;
}
EDIT
Here a new version of the program by calling function via the calling convention. I only wrote the new lines. The problem of this method is I can only store data inside a "void *" field. If I increase the size of structvoid, I got garbage behaviors.
// Structure that memories each argument
typedef struct {
void *i[1];
} structvoid;
int main(int argc, char** argv) {
// Variables to store the two functions and their arguments.
void * functions[2];
structvoid * data[2];
void *func1 = (void *)&test1;
// Let's start with a maximum of 5 arguments
void (*functionPtrc)(structurevoid, structurevoid, structurevoid, structurevoid, structurevoid);
// Definition of the argument of the first function test1
struct1 data1;
data1.nombre = 15;
data1.t = 'c';
data1.nombre2 = 30;
// and storing data.
structvoid *datac = malloc (sizeof (structvoid)*5);
memcpy(&datac[0], &data1.nombre, sizeof (data1.nombre));
memcpy(&datac[1], &data1.t, sizeof (data1.t));
memcpy(&datac[2], &data1.nombre2, sizeof (data1.nombre2));
data[0] = datac;
functions[0] = func1;
// Get the pointer to the first function (test1);
functionPtrc = functions[0];
// Call the function with the arguments. The unused argument will be ignored.
functionPtrc(data[0][0], data[0][1], data[0][2], data[0][3], data[0][4]);
}

Segmentation fault when we try to copy array of charcters in function [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 years ago.
Improve this question
I'm facing seg fault, when i try to copy some value to char array which is passed from main function.
please find attached code sample, please help me where i'm going wrong.
#include <stdio.h>
#include <string.h>
void getVal(char val[]){
strcpy(val[0],"abcdef"); //segfault.
}
int main(int argc, char **argv)
{
char val[64] = { 0 };
getVal(&val[0]);
printf("%s",val);
}
posted actual code, when char of array strcpy work fine but through function call it gives segfault. please help me .
#include <time.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include "ezxml.h"
static ezxml_t root;
void load_xml(char *root_node){
root = ezxml_parse_file(root_node);
printf("%p\n",root);
}
void getParamVal(char *objname, char val[]){
char *char_strip;
const char *tmp_buf[20];
int i=0;
ezxml_t get_child_tmp;
const char *attrvalue;
char_strip = strtok (objname,".");
while (char_strip != NULL)
{
tmp_buf[i] = char_strip;
char_strip = strtok (NULL, ".");
i++;
}
for (get_child_tmp = ezxml_child(root,tmp_buf[1]); get_child_tmp; get_child_tmp = get_child_tmp->next) {
attrvalue = ezxml_attr(get_child_tmp, "instance");
if(!(strcmp(attrvalue,tmp_buf[2]))){
ezxml_t get_child_level1;
for (get_child_level1 = ezxml_child(get_child_tmp,tmp_buf[3]); get_child_level1; get_child_level1 = get_child_level1->next) {
attrvalue = ezxml_attr(get_child_level1, "instance");
if(!(strcmp(attrvalue,tmp_buf[4]))){
ezxml_t get_child_level2;
for (get_child_level2 = ezxml_child(get_child_level1,tmp_buf[5]); get_child_level2; get_child_level2 = get_child_level2->next) {
attrvalue = ezxml_attr(get_child_level2,"instance");
if(!(strcmp(attrvalue,tmp_buf[6]))){
printf("%s\n",ezxml_child(get_child_level2,tmp_buf[7])->txt);
char s[10];
strcpy (s,ezxml_child(get_child_level2,tmp_buf[7])->txt); // fine with local array of char
printf("%s\n",s);
strcpy(val, ezxml_child(get_child_level2,tmp_buf[7])->txt); // problem gives segfault only diff is val is from other function.
}
}
}
}
}
}
}
int main(int argc, char **argv)
{
if (argc < 2){
printf("usage: ./test <xml file> ");
exit(1);
}
struct timeval tv;
unsigned int seconds=0, mseconds=0;
char val[64] = { 0 };
char objname[]="a.b.c.d.e.f.c";
load_xml(argv[1]);
gettimeofday(&tv, NULL);
seconds = tv.tv_sec;
mseconds = tv.tv_usec;
printf("START: [%u][%u]\n", seconds, mseconds);
getParamVal(&objname[0],&val[0]);
gettimeofday(&tv, NULL);
seconds = tv.tv_sec;
mseconds = tv.tv_usec;
printf(" END: [%u][%u]\n", seconds, mseconds);
return 0;
}
This is incorrect:
strcpy(val[0],"abcdef");
as the type of val[0] is a char and not a char*. The compiler should have emitted a warning regarding type mismatch:
$ gcc main.c -o prog
main.c: In function ‘getVal’:
main.c:6:5: warning: passing argument 1 of ‘strcpy’ makes pointer from
integer without a cast [enabled by default]
strcpy(val[0],"abcdef");
Don't ignore warnings and recommend compiling with warning level at maximum and to treat warnings as errors. A segmentation fault is occurring because the value of val[0] is, incorrectly, being used as a memory address which strcpy() is attempting to write to.
To correct, change to:
strcpy(val,"abcdef");
You need to pass a pointer to strcpy
strcpy(&val[0], "abcdef"); // '&' gets the address of firt element of 'val'
or write simply
strcpy(val, "abcdef");

Resources