how to pass struct as parameter and memcpy it in C? - c

I have the following code:
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int a[3];
} A;
typedef struct
{
int b;
} B;
typedef struct
{
A a;
B b;
} C;
void getC(C *c_p)
{
C c;
c.a.a[0] = 1;
c.b.b = 1;
memcpy(c_p, &c, sizeof(C));
}
int main()
{
C *c;
getC(c);
}
and it says the process returned, I really can not find the reason, I assume the memcpy part is not working, can anyone helps?

The error is in your main, where you pass an uninitialized pointer to getC. You should make it point to something, like this:
C c;
getC(&c);
or
C *c = malloc(sizeof(C));
getC(c);
...
free(c);
Moreover, you do not need to use memcpy with structs - an assignment will work as well:
void getC(C *c_p)
{
C c;
c.a.a[0] = 1;
c.b.b = 1;
*c_p = c; // No memcpy
}

Related

Returning a structure results in gibberish

I'm using structures in C and when I try to return a structure from a function it always results in gibberish when I try to print the contents of that structure in main.
Here is my code :
#include <stdio.h>
struct etudiant
{
int a;
int b;
int c;
};
typedef struct etudiant ETD;
ETD ajouter_etd()
{
ETD e;
scanf("%i%i%i", e.a, e.b, e.c);
return e;
}
void main()
{
ETD e;
e = ajouter_etd();
printf("%i%i%i", e.a, e.b, e.c);
}
You must pass the addresses of your variables to scanf as it needs to know where in memory to place the results of its conversions. This is done with the address-of operator (&).
#include <stdio.h>
typedef struct etudiant {
int a;
int b;
int c;
} ETD;
ETD ajouter_etd(void)
{
ETD e;
scanf("%i%i%i", &e.a, &e.b, &e.c);
return e;
}
int main(void)
{
ETD e;
e = ajouter_etd();
printf("%i%i%i\n", e.a, e.b, e.c);
}

transfer of pointer from function to function

I have a problem, because while loading data from the console, a bug is popping up I think it's a tricky thing to pass the indicator through the function, but I don't know how to fix it.
#include<stdio.h>
#include<stdlib.h>
typedef struct rn{
int n; /**numerator**/
unsigned d; /**denomirator**/
} rationalNumber;
typedef struct dot{
rationalNumber x;
rationalNumber y;
} point;
int gcd(int a, int b)
{
if(b!=0)
return gcd(b,a%b);
return a;
}
void input(rationalNumber *a)
{
int nwd;
if (scanf("%d/%u",&(a->n), &(a->d)) == 1) a->d=1;
else
{
nwd = abs(gcd(a->n, a->d));
a->n = a->n/nwd;
a->d = a->d/nwd;
}
}
void load_point(point *a, void(*function)(rationalNumber *))
{
function(&a->x);
function(&a->y);
}
int main(void)
{
rationalNumber *z;
point *a;
load_point(a, input);
return 0;
}
I've got this message : Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)
in this place : if (scanf("%d/%u",&(a->n), &(a->d)) == 1) a->d=1;
You're creating pointers that point to nothing in particular and then pass these on to the function which never initializes them, allocates memory for them, and trusts that they're valid, but they're not.
Remember that point* a is a pointer, not an allocation.
An easy solution is to use local variables instead of pointers:
int main(void)
{
rationalNumber z;
point a;
load_point(&a, input);
return 0;
}

Return Pointer from function

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;
}

Access struct member by an argument of function in C

int f(){
struct NUMBER {
int A;
int B;
};
struct NUMBER *num = malloc(sizeof(struct NUMBER));
num->A = 1;
num->B = 2;
int x = num->B;
return x;
}
int main(){
int z = f();
printf("%d\n", z);
}
Obviously, ./a.out will show 2.
My question: Can I access struct member by an argument of function? i.e. f(A) return 1, and f(B) return 2. Thanks a lot.
Not at all elegant, but I think it shows you what you need to do/know.
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
struct NUMBER {
int A;
int B;
};
struct NUMBER extNumber = {1, 2};
int f(int offset) {
int iRet = -1;
if (offset == offsetof(struct NUMBER, A)) {
iRet = extNumber.A;
} else if (offset == offsetof(struct NUMBER, B)) {
iRet = extNumber.B;
}
return iRet;
}
int main (int argc, char **argv) {
struct NUMBER number;
int iVal;
iVal = f(offsetof(struct NUMBER, A));
printf ("A : %d\n", iVal);
iVal = f(offsetof(struct NUMBER, B));
printf ("B : %d\n", iVal);
}
Can I access struct member by an argument of function?
I think you are also assuming struct is not visible outside the function. Now if the person who wrote main does not have visibility into the function (say it is part of a library), then the answer is NO.
Otherwise if author of main can see internals of the function, then: Can someone come up with a fancy way to access struct member inside the function via function argument? Towards that lets think what does f(A) mean? Here, A is a name of struct member, so do you mean passing char A to f and translating that to struct member inside f [e.g. result = *(int *)num+(inchar-'A') where inchar is aninput parameter to the function of type char]. Similarly, one can imagine other ways.
As far as I understand your problem, the cleanest and most "C-like" solution is to pass a pointer to your struct to f(), where you populate it:
typedef struct _NUMBER
{
int A;
int B;
}
NUMBER;
void f (NUMBER* pvNumber)
{
pvNumber->A = 1;
pvNumber->B = 2;
return;
}
Call it like this:
int main ()
{
NUMBER vNumber;
int z;
f (&vNumber);
z = vNumber.A; // or vNumber.B
return 0;
}
So you don't select the desired member inside f(), but outside of it.
Yes. you need to define some way to access to member desired, this is usually done with constants, or an enum. As an aside, you should always check the pointer returned by malloc() before using it.
#define GET_A (0)
#define GET_B (1)
int f(int selector){
struct NUMBER {
int A;
int B;
};
int result;
struct NUMBER *num = malloc(sizeof(struct NUMBER));
if (!num)
return -1; // or some other error code...
num -> A = 1;
num -> B = 2;
switch(selector)
{
case GET_A: result = num->A; break;
case GET_B: result = num->B; break;
// etc... if you have more members in your struct.
default: result = -1; break; // some error code.
}
free(num)
return result;
}
int main(){
int z = f(GET_B);
printf( "%d\n" , f(GET_B));
}

Pass pointer to struct by reference in C

Take in mind the following piece of code:
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int a;
int b;
int c;
}A;
A *test;
void init(A* a)
{
a->a = 3;
a->b = 2;
a->c = 1;
}
int main()
{
test = malloc(sizeof(A));
init(test);
printf("%d\n", test->a);
return 0;
}
It runs fine! Now imagine that I want to use the malloc function outside the main itself without returning a pointer to the struct. I would put malloc inside init and pass test adress. But this doesnt seem to work.
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int a;
int b;
int c;
}A;
A *test;
void init(A** a)
{
*a = malloc(sizeof(A));
*a->a = 3;
*a->b = 2;
*a->c = 1;
}
int main()
{
init(&test);
printf("%d\n", test->a);
return 0;
}
It keeps telling me that int a(or b/c) is not a member of the struct A when I use the pointer.
Your problem is operator precedence. The -> operator has higher precedence than the * (dereference) operator, so *a->a is read as if it is *(a->a). Change *a->a to (*a)->a:
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int a;
int b;
int c;
}A;
A *test;
void init(A** a)
{
*a = malloc(sizeof(A));
(*a)->a = 3;
(*a)->b = 2;
(*a)->c = 1;
}
int main()
{
init(&test);
printf("%d\n", test->a);
return 0;
}
You must add parenthesis:
void init(A **a)
{
*a = malloc(sizeof(A)); // bad you don't verify the return of malloc
(*a)->a = 3;
(*a)->b = 2;
(*a)->c = 1;
}
But it's good practice to do this:
void init(A **a)
{
A *ret = malloc(sizeof *ret); // we want the size that is referenced by ret
if (ret != NULL) { // you should check the return of malloc
ret->a = 3;
ret->b = 2;
ret->c = 1;
}
*a = ret;
}
You need to write (*a)->a = 3; for reasons of precedence.
Even though it's not a direct answer to your question, since we're in the vicinity of initialization I'd like to point out that C11 gives you a nicer syntax to initialize structs:
void init(A **a)
{
A *ret = malloc(sizeof *ret); // we want the size that is referenced by ret
if (ret != NULL) { // you should check the return of malloc
*ret = (A) {3, 2, 1};
// or
*ret = (A) { .a = 3, .b = 2, .c = 1 };
}
*a = ret;
}
Another advantage is that any uninitialized members are zeroed.

Resources