I am new in C and literally trying to return pointer from my function to the pointer variable and have this "[Warning] assignment makes pointer from integer without a cast" no idea why compiler defines it as an int.
Can't declare my function before main as well, it throws this "undefined reference to `free_block'".
#include <stdio.h>
#include <stdlib.h>
struct block{
int num;
};
int main(int argc, char *argv[]) {
struct block *b;
b = free_block();
struct block *free_block(){
struct block *b = NULL;
return b;
}
return 0;
}
Thank you
Yea, my fault I know not too much about c syntax and had no idea about nested functions, soz.
But what could be wrong in this case:
I am trying to make my own memory allocator without using malloc or calloc functions. In my code I have the same Warning on the line with pointer = free_space_get(size);, here I have no more nested func(), my methods defined before main(), but still have no idea do I have to declare my functions or no, coz in the answer given to me it worked fine as soon as functions were defined before the main().
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct header{
size_t size;
struct header *next;
unsigned int free;
};
void *m_alloc(size_t size){
size_t total_size;
void *block;
struct header *pointer;
if(!size)
return NULL;
pointer = free_space_get(size);
if(pointer){
pointer->free = 0;
return (void*)(pointer + 1);
}
}
struct header *get_free_space(size_t size){
struct header *b = NULL;
return b;
}
int main() {
return 0;
}
Your code can be re-written as
#include <stdio.h>
#include <stdlib.h>
struct block{
int num;
};
struct block *free_block(){
struct block *b = NULL;
return b;
}
int main(int argc, char *argv[]) {
struct block *b;
b = free_block();
if(b == NULL) // Checking whether pointer is returned
printf("\n Recieved NULL \n");
return 0;
}
Related
I am not able to initialize all three pointers to struct S, and I don't know why.
I am using a fixed-length array as stack to store values.
The header file is created this way to hide information (struct S), and should be kept as generic as possible.
main.c
// main.c
#include <stdio.h>
#include "stack_exercise4.h"
int main(void) {
Stack *stack_1, *stack_2, *stack_3;
int a, b;
make_empty(stack_1);
make_empty(stack_2);
make_empty(stack_3);
return 0;
}
Problem is, after Stack *stack_1, *stack_2, *stack_3, only stack_2 has a valid address for Struct stack. stack_1 and stack_3 have some strange looking addresses, and I can't assign any values to stack_1->top, nor stack_3->top. What is the problem?
header file
// stack_exercise4.h
#ifndef STACK_EXERCISE4_H
#define STACK_EXERCISE4_H
#include <stdbool.h> /* C99 only */
typedef struct S Stack; /* incomplete type to hide the content
of S. */
void make_empty(Stack *s);
bool is_empty(const Stack *s);
bool is_full(const Stack *s);
void push(Stack *s, int i);
int pop(Stack *s);
#endif
stack source file
// stack_exercise4a.c
#include "stack_exercise4.h"
#include <stdio.h>
#define MAX_STACK_SIZE (10)
struct S {
int top;
int contents[MAX_STACK_SIZE];
};
void make_empty(Stack *s) {
s->top = 0;
}
bool is_empty(const Stack *s) {
return (s->top <= 0);
}
bool is_full(const Stack *s) {
return (s->top >= MAX_STACK_SIZE - 1);
}
void push(Stack *s, int i) {
if (!is_full(s)){
(s->contents)[s->top++] = i;
} else {
printf("Failed to push, Stack is full.\n");
}
}
int pop(Stack *s) {
return (s->contents)[s->top--];
}
The stack pointers must point on memory spaces before being dereferenced in make_empty(). Something like this could be the starting point: make_empty() allocates the memory space.
void make_empty(Stack **s) {
(*s) = (struct S *)malloc(sizeof(struct S));
(*s)->top = 0;
}
And so the initialization of the pointers would be:
make_empty(&stack_1);
make_empty(&stack_2);
make_empty(&stack_3);
Declare stack_X on stack instead.
#include <stdio.h>
#include "stack_exercise4.h"
int main(void) {
Stack stack_1 = {0}, stack_2 = {0}, stack_3 = {0};
int a, b;
make_empty(&stack_1);
make_empty(&stack_2);
make_empty(&stack_3);
return 0;
}
Otherwise, I't would need to have constructor/destructor for your Stack data structure e.g new_stack(Stack *ptr) del_stack(Stack *ptr). For beginner, I would recommend to use stack instead of heap (stay away from malloc).
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
I'm fully prepared to be told that I'm doing something stupid/wrong; this is what I expect.
I'm getting a feel for structures and coming a cropper when it comes to accessing the fields from the pointers. Code to follow.
matrix.h:
#ifndef MATRIX_H_INCLUDED
#define MATRIX_H_INCLUDED
#include <stdlib.h>
typedef struct
{
size_t size;
int* vector;
} vector_t;
#endif // MATRIX_H_INCLUDED
main.c:
#include <stdio.h>
#include <stdlib.h>
#include "matrix.h"
vector_t* vector_new(size_t size)
{
int vector[size];
vector_t v;
v.size = size;
v.vector = vector;
return &v;
}
int main(int argc, char* argv[])
{
vector_t* vec = vector_new(3);
printf("v has size %d.\n", vec->size);
printf("v has size %d.\n", vec->size);
return EXIT_SUCCESS;
}
So this is a very simple program where I create a vector structure of size 3, return the pointer to the structure and then print its size. This, on the first print instance is 3 which then changes to 2686668 on the next print. What is going on?
Thanks in advance.
You are returning a pointer to a local variable v from vector_new. This does not have a slightest chance to work. By the time vector_new returns to main, all local variables are destroyed and your pointer points to nowhere. Moreover, the memory v.vector points to is also a local array vector. It is also destroyed when vector_new returns.
This is why you see garbage printed by your printf.
Your code has to be completely redesigned with regard to memory management. The actual array has to be allocated dynamically, using malloc. The vector_t object itself might be allocated dynamically or might be declared as a local variable in main and passed to vector_new for initialization. (Which approach you want to follow is up to you).
For example, if we decide to do everything using dynamic allocation, then it might look as follows
vector_t* vector_new(size_t size)
{
vector_t* v = malloc(sizeof *v);
v->size = size;
v->vector = malloc(v->size * sizeof *v->vector);
return v;
}
(and don't forget to check that malloc succeeded).
However, everything that we allocated dynamically we have to deallocate later using free. So, you will have to write a vector_free function for that purpose.
Complete re-write of answer to address your question, and to provide alternate approach:
The code as written in OP will not compile: &v is an illegal return value.
If I modify your code as such:
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
size_t size;
int* vector;
} vector_t;
vector_t* vector_new(size_t size)
{
int vector[size];
vector_t v, *pV;
pV = &v;
pV->size = size;
pV->vector = vector;
return pV;
}
int main(int argc, char* argv[])
{
vector_t* vec = vector_new(3);
printf("v has size %d.\n", vec->size);
printf("v has size %d.\n", vec->size);
getchar();
return EXIT_SUCCESS;
}
It builds and runs, but returns unintended values for vec->size in main() due to the local scope of that variable in the function vector_new.
Recommend creating globally visible instance of your struct, and redefine vector_new() to int initVector(void):
#include <stdlib.h>
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
typedef struct
{
size_t size;
int* vector;
} vector_t;
vector_t v, *pV;//globally visible instance of struct
int initVector(void)
{
int i;
pV->size = SIZE;
pV->vector = calloc(SIZE, sizeof(int));
if(!pV->vector) return -1;
for(i=0;i<SIZE;i++)
{
pV->vector[i] = i;
}
return 0;
}
int main(int argc, char* argv[])
{
int i;
pV = &v; //initialize instance of struct
if(initVector() == 0)
{
printf("pV->size has size %d.\n", pV->size);
for(i=0;i<SIZE;i++) printf("pV->vector[%d] == %d.\n", i, pV->vector[i]);
}
getchar(); //to pause execution
return EXIT_SUCCESS;
}
Yields these results:
You still need to write a freeVector function to undo all the allocated memory.
I created a structure and wanted to assign the values to a Function Pointer of another structure. The sample code I wrote is like below. Please see what else I've missed.
#include <stdio.h>
#include <string.h>
struct PClass{
void *Funt;
}gpclass;
struct StrFu stringfunc;
struct StrFu{
int a ;
char c;
};
Initialise(){
}
main()
{
stringfunc.a = 5;
stringfunc.c = 'd';
gpclass.Funt = malloc(sizeof(struct StrFu));
gpclass.Funt = &stringfunc;
memcpy(gpclass.Funt,&stringfunc,sizeof(struct StrFu));
printf("%u %u",gpclass.Funt->a,gpclass.Funt->c);
}
There are several problems:
A function pointer is not the same as void *, in fact you cannot rely on being able to convert between them.
You shouldn't cast the return value of malloc() in C.
You shouldn't call malloc(), then overwrite the returned pointer.
You don't need to use malloc() to store a single pointer, just use a pointer.
You shouldn't use memcpy() to copy structures, just use assignment.
There are two valid main() prototypes: int main(void) and int main(int argc, char *argv[]), and you're not using either.
there is lots of problem in your code , I try to correct it ,hope it will help
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct PClass{
void *Funt;
}gpclass;
struct StrFu{
int a ;
char c;
};
struct StrFu stringfunc;
int main()
{
stringfunc.a = 5;
stringfunc.c = 'd';
gpclass.Funt = malloc(sizeof(struct StrFu));
gpclass.Funt = &stringfunc;
memcpy(gpclass.Funt,&stringfunc,sizeof(struct StrFu));
printf("%d %c",((struct StrFu*)gpclass.Funt)->a,((struct StrFu*)gpclass.Funt)->c);
return 0;
}
it outputs
5 d
I want to learn more about using function pointers in C structs as a way to emulate objects-oriented programming, but in my search, I've just found questions like this where the answer is simply to use a function pointer without describing how that would work.
My best guess is something like this
#include <stdio.h>
#include <stdlib.h>
struct my_struct
{
int data;
struct my_struct* (*set_data) (int);
};
struct my_struct* my_struct_set_data(struct my_struct* m, int new_data)
{
m->data = new_data;
return m;
}
struct my_struct* my_struct_create() {
struct my_struct* result = malloc((sizeof(struct my_struct)));
result->data = 0;
result->set_data = my_struct_set_data;
return result;
}
int main(int argc, const char* argv[])
{
struct my_struct* thing = my_struct_create();
thing->set_data(1);
printf("%d\n", thing->data);
free(thing);
return 0;
}
But that give me compiler warnings warning: assignment from incompatible pointer type, so obviously I'm doing something wrong. Could someone please provide a small but complete example of how to use a function pointer in a C struct correctly?
My class taught in C does not even mention these. It makes me wonder whether these are actually used by C programmers. What are the advantages and disadvantages of using function pointers in C structs?
The answer given by Andy Stow Away fixes my compiler warning, but doesn't answer my second question. The comments to that answer given by eddieantonio and Niklas R answer my second question, but don't fix my compiler warning. So I'm pooling them together into one answer.
C is not object-oriented and attempting to emulate object-oriented design in C usually results in bad style. Duplicating methods called on structs so that they can be called using a pointer to the struct as I have in my example is no exception. (And frankly, it violates DRY.) Function pointers in structs are more useful for polymorphism. For example, if I had a struct vector that represented a generic container for a linear sequence of elements, it might be useful to store a comparison_func member that was a function pointer to allow sorting and searching through the vector. Each instance of the vector could use a different comparison function. However, in the case of a function that operates on the struct itself, it is better style to have a single separate function that is not duplicated in the struct.
This makes the answer to what is correct more complicated. Is what is correct how to make my above example compile? Is it how to reformat my above example so that it has good style? Or is it what is an example of a struct that uses a function pointer the way C programmer would do it? In formulating my question, I did not anticipate the answer being that my question was wrong. For completeness, I will provide an example of each answer to the question.
Fixing the Compiler Warning
#include <stdio.h>
#include <stdlib.h>
struct my_struct
{
int data;
struct my_struct* (*set_data) (struct my_struct*, int);
};
struct my_struct* my_struct_set_data(struct my_struct* m, int new_data)
{
m->data = new_data;
return m;
}
struct my_struct* my_struct_create()
{
struct my_struct* result = malloc((sizeof(struct my_struct)));
result->data = 0;
result->set_data = my_struct_set_data;
return result;
}
int main(int argc, const char* argv[])
{
struct my_struct* thing = my_struct_create();
thing->set_data(thing, 1);
printf("%d\n", thing->data);
free(thing);
return 0;
}
Reformatting the Style
#include <stdio.h>
#include <stdlib.h>
struct my_struct
{
int data;
};
void my_struct_set_data(struct my_struct* m, int new_data)
{
m->data = new_data;
}
struct my_struct* my_struct_create()
{
struct my_struct* result = malloc((sizeof(struct my_struct)));
result->data = 0;
return result;
}
int main(int argc, const char* argv[])
{
struct my_struct* thing = my_struct_create();
my_struct_set_data(thing, 1);
printf("%d\n", thing->data);
free(thing);
return 0;
}
Demonstrating a Use for Function Pointer in Structs
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct my_struct
{
void* data;
int (*compare_func)(const void*, const void*);
};
int my_struct_compare_to_data(struct my_struct* m, const void* comparable)
{
return m->compare_func(m->data, comparable);
}
struct my_struct* my_struct_create(void* initial_data,
int (*compare_func)(const void*, const void*))
{
struct my_struct* result = malloc((sizeof(struct my_struct)));
result->data = initial_data;
result->compare_func = compare_func;
return result;
}
int int_compare(const void* a_pointer, const void* b_pointer)
{
return *(int*)a_pointer - *(int*) b_pointer;
}
int string_compare(const void* a_pointer, const void* b_pointer)
{
return strcmp(*(char**)a_pointer, *(char**)b_pointer);
}
int main(int argc, const char* argv[])
{
int int_data = 42;
struct my_struct* int_comparator =
my_struct_create(&int_data, int_compare);
char* string_data = "Hello world";
struct my_struct* string_comparator =
my_struct_create(&string_data, string_compare);
int int_comparable = 42;
if (my_struct_compare_to_data(int_comparator, &int_comparable) == 0)
{
printf("The two ints are equal.\n");
}
char* string_comparable = "Goodbye world";
if (my_struct_compare_to_data(string_comparator,
&string_comparable) > 0)
{
printf("The first string comes after the second.\n");
}
free(int_comparator);
free(string_comparator);
return 0;
}
In your struct definition, change it to
struct my_struct
{
int data;
struct my_struct* (*set_data) (struct my_struct*,int);
};
and now use the above function pointer in main as
thing->set_data(thing,1);