Why does my char array not print anything? - arrays

In c I am trying to assign a char array inside a struct with a user provided value, here is my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct person
{
char name[20];
int age;
};
struct person *assign(char arr[], int age)
{
struct person *x = malloc(sizeof(struct person));
x->name[20] = arr[20];
x->age = 21;
return x;
}
int main()
{
char name[20] = "Arthur morgan";
int age = 34;
struct person* person1 = assign(name, age);
printf("name: %s\n", person1->name);
printf("age: %d\n", person1->age);
return 0;
}
The problem is that the name prints nothing for some reason, the age however prints as expected.
Why is the name not printing correctly?

x->name[20] = arr[20];
It does not copy the array
It copies 1 character and you are accessing array outside its bounds which is undefined behaviour (UB)
It is better to use objects not types in sizeof
Always check the result of malloc
You need to copy the string using strcpy function
struct person *assign(char arr[], int age)
{
struct person *x = malloc(sizeof(*x));
if(x)
{
strcpy(x->name,arr);
x->age = 21;
}
return x;
}
https://godbolt.org/z/vKddb4b9a

Related

initialise constructor values of structure using pointer in c [duplicate]

This question already has answers here:
How do malloc() and free() work?
(13 answers)
Closed 3 years ago.
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
struct Person {
char name[50];
int year_of_birth;
char sex[7];
char father[50];
char mother[50];
char significant_other[50];
char children[50];
};
struct Person* person_constructor(char *name, int year_of_birth, char *sex);
int main(){
struct Person* p1 = person_constructor("Abbas", 1970, "male");
}
struct Person* person_constructor(char *name, int year_of_birth, char *sex) {
struct Person *p;
printf("%s",*name);
printf("%s",*sex);
printf("%d",&year_of_birth);
// how to initalise these here and return name, age and sex everytime , can you tell me in print function
}
i want to do :
Person* person_constructor(char *name, int year_of_birth, char *sex);
A person with the given arguments and return it.
Also allocate memory.
In example code bellow you can find one of possible solutions to your question.
In C language is not possible to return more then one variable, but you can return pointer to constructed structure object and access structure members using notation stuct_ptr->struct_member.
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
struct Person {
char name[50];
int year_of_birth;
char sex[7];
char father[50];
char mother[50];
char significant_other[50];
char children[50];
};
struct Person* person_constructor(char *name, int year_of_birth, char *sex);
int main(){
struct Person* p1 = person_constructor("Abbas", 1970, "male");
/* it is not possible to return more variables in C */
/* you can use pointer to access members from constructed structure: */
printf("print from main:\n %s %d %s \n", p1->name, p1->year_of_birth, p1->sex);
if( p1 != NULL) free(p1); /* do not forget do deallocate something taht is allocated */
return 0;
}
struct Person* person_constructor(char *name, int year_of_birth, char *sex) {
struct Person *p = calloc(1, sizeof(struct Person));
if( p == NULL ) return p; /* memory alocation failed! */
strcpy(p->name, name);
p->year_of_birth = year_of_birth;
strcpy(p->sex, sex);
printf("print from constructor:\n");
printf("%s ",p->name);
printf("%s ",p->sex);
printf("%d \n",p->year_of_birth);
return p;
}

Having trouble with char pointers

I'm having trouble with char pointers. I'm trying to get the value from the store_stuff function and print it into the main function. How can I do this?
#include <stdio.h>
#include <string.h>
#include <assert.h>
void store_stuff(char *name, int *age);
int main(void) {
char *name;
int age;
store_stuff(&name, &age); // I'm having trouble here
printf("Name: %s\n", name);
printf("Age: %d\n", age);
}
void store_stuff(char **name, int *age) {
*name = "John";
*age = 31;
}
https://ideone.com/5HOPGQ
#include <stdio.h>
#include <string.h>
#include <assert.h>
char *store_stuff(char **name, int *age);
int main(void) {
char *name;
int age;
store_stuff(&name, &age); // I'm having trouble here
printf("Name: %s\n", name);
printf("Age: %d\n", age);
}
char *store_stuff(char **name, int *age) {
*name = "John";
*age = 31;
return *name;
}
Make it
void store_stuff(char** name, int* age)
{
*name = "John";
*age = 31;
}
You need that pointer to a pointer for name assignment to make its way out of store_stuff
Also you need to change your definition of
char name
to
char* name
Since name itself wants to be a pointer to interact as a string
EDIT: And of course, be sure to make your prototype consistent at the top with void store_stuff(char** name, int* age);

How to return an array of structure by reference?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct data{
char name[20];
char lastname[25];
int age;
}person;
void insert(person *p,int *num);
int main()
{
int num;
person p;
insert(&p,&num);
printf("Name: %s",p[0].nome); /* Here i would print the first struct by
my array, but: is not array or not pointer Why?? */
}
void insert(person *p, int *num)
{
int dim;
person *arr;
printf("Insert how many people do you want? "); /* How many index the
array should have */
scanf("%d",&dim);
arr = (person *) malloc(dim*sizeof(person)); /* I'm not sure for
this explicit cast. */
for(int i = 0; i < dim; i++)
{
printf("Insert name: ");
scanf("%s",arr[i].name);
printf("Insert lastname: ");
scanf("%s",arr[i].lastname);
printf("Insert age:': ");
scanf("%d",&arr[i].age);
}
*num = dim;
*p = *arr;
}
I've tried: `person *insert(int *num)
And it's works,but how can pass an array reference?`
This programm should ask how many person do you want to insert ( in function insert) and with a for, he should ask name,surname,age.
After the insert, he should print, but for quick, i would tried with first element (index) of array (structs).
You can't return entire array from the function, but you can return the base location of the array. For example you can do like this : person *insert(int *sz);. But i see in your code you're passing &p and the &num variable into the insert method, maybe you want to modify them within that function and manipulate it afterwards in your main(). For that i would have these recommendations:
Change Line 16 person p to person *p. Since p is supposed to hold base value of an array. Remember array name is nothing but a base address to the first element of the list.
Change your function definition to recieve person** rather than person*. Since you want to modify a pointer variable and therefore you'd need a pointer to a pointer variable. Change it like this:` void insert(person **p, int *num)
Free the memory after usage; add a free(p) at the end of main.
`

How to allocate memory with different type in C?

I have the following code in C:
typedef struct
{
int age;
int phoneNumber;
} Student;
typedef struct
{
int id;
int student[1];
} People;
#define NUM_OF_PEOPLE
void *p = malloc(sizeof(People) + sizeof(int) * NUM_OF_PEOPLE + sizeof(Student) * NUM_OF_PEOPLE);
How could I find the pointer to the memory point to the first element of struct Student in the memory?
I try to do it in the following way:
int i = 0;
for(i = 0; i < NUM_OF_PEOPLE; i++)
{
Student * student_p = p.student[NUM_OF_PEOPLE];
}
It does not work, so can we allocate memory in the way?
And how to find the first element of struct Student in the memory?
What you have is an ancient way of having a flexible array member, which was technically also undefined behavior.
You are looking for this.
First, you need to define your struct like this (I don't know what the ints before the Students are, so let's just call it id):
typedef struct
{
int age;
int phoneNumber;
} Student;
typedef struct
{
int id;
Student student;
} StudentAndId;
typedef struct
{
int id;
StudentAndId students[];
} People;
Note the lack of size in the array inside People. Now you do this:
People *p = malloc(sizeof(People) + sizeof(StudentAndId[NUM_OF_PEOPLE]));
Then you can access students inside p as if it was an array of NUM_OF_PEOPLE elements.
Remember to compile with C99 (or C11) support. With gcc that would be -std=c99 or -std=gnu99.
This will allocate memory for storing the date but how you access it depends on how you store date. using C pointers you can store and access data using this structure and allocation but accessing the members will not be direct. it will involve pointer arithmetic. So better to use other structure if possible. If using this way of allocation then you need to do pointer arithmetic to get the next elements.
Try this:
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int age;
int phoneNumber;
} Student;
typedef struct
{
int id;
int student[1];
} People;
#define NUM_OF_PEOPLE 10
int main()
{
People *p = malloc(sizeof(People) + sizeof(int) * NUM_OF_PEOPLE + sizeof(Student) * NUM_OF_PEOPLE);
int* id = (int*)(p+1);
Student* s = (Student*)(id+NUM_OF_PEOPLE);
printf("Size of People : %d\n", sizeof(People));
printf("p points to : %p\n", p);
printf("id points to : %p\n", id);
printf("s points to : %p\n", s);
}
Here's a sample output:
Size of People : 8
p points to : 0x80010460
id points to : 0x80010468
s points to : 0x80010490
You may want to add the id field to your Student data structure, e.g.:
typedef struct {
int id;
int age;
int phoneNumber;
} Student;
Then, you can define a structure having a fixed header (in this case, this can be the number of students), followed by a variable-sized array of Students:
#define ARRAY_OF_ANY_SIZE 1
typedef struct {
int count;
Student students[ARRAY_OF_ANY_SIZE];
} People;
This blog post explains this technique of having "arrays of size 1", including a discussion of the alignment problem.
I won't repeat the original blog post code here. Just consider that you can use the portable offsetof() instead of the Windows-specific FIELD_OFFSET() macro.
As a sample code, you may want to consider the following:
#include <stdio.h> /* For printf() */
#include <stddef.h> /* For offsetof() */
#include <stdlib.h> /* For dynamic memory allocation */
typedef struct {
int id;
int age;
int phoneNumber;
} Student;
#define ARRAY_OF_ANY_SIZE 1
typedef struct {
int count;
Student students[ARRAY_OF_ANY_SIZE];
} People;
int main(int argc, char* argv[]) {
People* people;
const int numberOfStudents = 3;
int i;
/* Dynamically allocate memory to store the data structure */
people = malloc(offsetof(People, students[numberOfStudents]));
/* Check memory allocation ... */
/* Fill the data structure */
people->count = numberOfStudents;
for (i = 0; i < numberOfStudents; i++) {
people->students[i].id = i;
people->students[i].age = (i+1)*10;
people->students[i].phoneNumber = 11000 + i;
}
/* Print the data structure content */
for (i = 0; i < people->count; i++) {
printf("id: %d, age=%d, phone=%d\n",
people->students[i].id,
people->students[i].age,
people->students[i].phoneNumber);
}
/* Release the memory allocated by the data structure */
free(people);
return 0;
}
Output:
id: 0, age=10, phone=11000
id: 1, age=20, phone=11001
id: 2, age=30, phone=11002

creating, passing, getting back Array of a Struct and loop throuh it in C

I need to execute a function that returns array of a specified struct with variable length. Then I should loop through the returned array.
example struct :
typedef struct student {
int id;
char *name;
int grade;
} Student;
function prototypes 1 :
Student *students;
students = findStudentByGrade(int grade);
function prototypes 2 :
Student *students;
int retval = findStudentByGrade(&students, int grade);
I am bit confused on above methods. How can correctly define a array of struct? call function ? and loop through it untill end? Can some one help me please.
You can do this in this way. This code is working. I tested in CodeLite.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct student {
int id;
char *name;
} Student;
Student *findStudent(int *asize, const int grade);
int main(void)
{
Student *stds;
int asize = 0;
stds = findStudent(&asize, 5);
int i;
for (i = 0; i < asize; i++) {
printf("ID : %i\n", stds[i].id);
}
return 0;
}
Student *findStudent(int *asize, const int grade)
{
struct student *stds = malloc(sizeof(struct student) * 3);
stds[0].id = 10;
stds[1].id = 20;
stds[2].id = 40;
*asize = 3;
return stds;
}
Get the array of struc as returned statement and pass an int variable with argument list to get the size back and simply loop through using a for loop. Or else you will find problem in looping. It is more easy to get the array size from the function which create the array.
I mean this is quite a basic question, but:
Defining array of your structures would look like:
int size = ...;
Student *students = (Student*) malloc(sizeof(Student) * size);
Then just pass that to the function (both size and the array) and then just loop until i < size.
Ofcourse, don't forget to:
free(students);
at the end.

Resources