473,394 Members | 1,481 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Functions, arrays, structs and passing by reference

S.
Hi all,

Can someone please help me with this?

I have the following struct:
typedef struct {
char *name;
int age;
} Student;
I have the following prototype declaration:
void addStudent(Student *arr_students);

In my main, I want to have an array called 'students' which is
composed of the Student struct. I then want to pass a function that
will allow me to create a Student record using pass-by-reference:
int main() {

Student students[CLASSSIZE]; /* array of student
struct's? */

addStudent(&students[0]);
printf("%s",&students[0].name);
return 0;
}

The following is my function to add a student:
void addStudent(Student *arr_student) {
char *name;

printf("\nEnter student name: ");
scanf("%s",&name);
*arr_student[0].name = name;

return;
}

I guess I have two questions before everyone dives into how wrong I
have done everything.
Q1. When I compile this I get the following error, could someone
please help explain why this occurs and how I can fix my code to
prevent this warning?
"test.c", line 25: warning: improper pointer/integer
combination: op "="
Q2. When I run my program, I am prompted with "Enter student name: "
and I enter in a name, I then receive the following error, can someone
please explain why this is happening too?
"Segmentation Fault"

I have a feeling I have declared my array of Student struct wrong and
I am also not passing the array through to the function correctly
which is causing both my problems. I have searched all over the
internet and in this discussion group but can't find an example
related to what I am trying to do.

Any help would be appreciated.

Kind regards,
S.

Below is my program:
#include <stdio.h>
#define CLASSSIZE 10

typedef struct {
char *name;
int age;
} Student;

void addStudent(Student *arr_students);

int main() {

Student students[CLASSSIZE]; /* array of student struct's?*/

addStudent(&students[3]);
printf("%s",&students[3].name);
return 0;
}

void addStudent(Student *arr_student) {
char *name;

printf("\nEnter student name: ");
scanf("%s",&name);
*arr_student[3].name = name;

return;
}
Jun 27 '08 #1
8 3471
S. wrote:
Hi all,

Can someone please help me with this?

I have the following struct:
typedef struct {
char *name;
int age;
} Student;
I have the following prototype declaration:
void addStudent(Student *arr_students);

In my main, I want to have an array called 'students' which is
composed of the Student struct. I then want to pass a function that
will allow me to create a Student record using pass-by-reference:
int main() {

Student students[CLASSSIZE]; /* array of student
struct's? */

addStudent(&students[0]);
printf("%s",&students[0].name);
return 0;
}

The following is my function to add a student:
void addStudent(Student *arr_student) {
char *name;

printf("\nEnter student name: ");
scanf("%s",&name);
*arr_student[0].name = name;

return;
}

I guess I have two questions before everyone dives into how wrong I
have done everything.
Q1. When I compile this I get the following error, could someone
please help explain why this occurs and how I can fix my code to
prevent this warning?
"test.c", line 25: warning: improper pointer/integer
combination: op "="
Q2. When I run my program, I am prompted with "Enter student name: "
and I enter in a name, I then receive the following error, can someone
please explain why this is happening too?
"Segmentation Fault"

I have a feeling I have declared my array of Student struct wrong and
I am also not passing the array through to the function correctly
which is causing both my problems. I have searched all over the
internet and in this discussion group but can't find an example
related to what I am trying to do.

Any help would be appreciated.

Kind regards,
S.

Below is my program:
#include <stdio.h>
#define CLASSSIZE 10

typedef struct {
char *name;
name is declared as a pointer to a char (or char array).
int age;
} Student;

void addStudent(Student *arr_students);

int main() {

Student students[CLASSSIZE]; /* array of student struct's?*/

addStudent(&students[3]);
printf("%s",&students[3].name);
return 0;
}

void addStudent(Student *arr_student) {
char *name;
name here is a local variable that can hold a pointer to a character or
character array. Only the size of a pointer is allocated to it. It is not
pointing at anything at this point, some random bit of memory maybe, or
maybe 0
printf("\nEnter student name: ");
scanf("%s",&name);
You are now trying to store the characters entered at the location that name
is pointing to... but, name is still pointing into lala land. No memory has
actually been allocated to hold the characters entered.
*arr_student[3].name = name;

return;
}
Now, you can, to fix this in your current design, malloc memory in
addStudent to hold the student name and point the structure name to it, but
thinknig about it, you're going to have to set some size. 10? 20? 30?
Whatever it is, it probably won't be big enough. Anyway, why go through all
this trouble because then you have to free the memory when your program is
done. You might as well just allocate it in your structure in the first
place.

typedef struct {
char name[30];
int age;
} Student;

now you can just scanf("%s", arr_student->name )
--
Jim Langston
ta*******@rocketmail.com
Jun 27 '08 #2
Jim Langston said:

<snip>
now you can just scanf("%s", arr_student->name )
....but shouldn't, because it doesn't protect the buffer against too much
data being read into it. There are better ways to capture strings than
scanf (and better ways to use scanf than unadorned %s).

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jun 27 '08 #3
On 1 May, 02:41, "S." <sianeag...@gmail.comwrote:
I have the following struct:
typedef struct {
* * * * char *name;
* * * * int age;

} Student;

I have the following prototype declaration:
void addStudent(Student *arr_students);

In my main, I want to have an array called 'students' which is
composed of the Student struct. I then want to pass a function that
will allow me to create a Student record using pass-by-reference:
C doesn't support pass-by-reference (I'm not just being pedantic
I think its part of your problem). In C all arguments are passed by
value. You can pass pointers which comes close to emulating
call-by-reference.

int main() {

* * * * Student students[CLASSSIZE]; */* array of student
struct's? * * **/
yes that's fine

>
* * * * addStudent(&students[0]);
ok
using =to mean "type is"

students =Student[] =array-of-Student
students[0] =Student
&students[0] =Student* =ptr-to-Student

which is what the function wants.

* * * * printf("%s",&students[0].name);
what's the & for?

students[0].name =char*
&students[0].name =char

oops! printf() is expecting a char* and you gave it a char
* * * * return 0;

}

The following is my function to add a student:
void addStudent(Student *arr_student) {
I find the name confusing. arr_student is NOT an
array of Students but a pointer to a student.

* * * * char *name;

* * * * printf("\nEnter student name: ");
* * * * scanf("%s",&name);
bang! name is pointing a random memory
(or no memory at all)
* * * * *arr_student[0].name = name;
Like I said arr_student isn't an array...

Ok, I'm confused are you trying to pass a single Student or an
array. C may not distinguish these cases but you need to be
clear in your mind which you are trying to do. Does addStudent()
add a single student? There's no loop so I assume so. So logically
addStudent only needs a single Student.

arr_student =Student*
arr_student[0] =Student
arr_student[0].name =char*
*arr_student[0].name =char

You probably want

(*arr_student).name

or the shortcut notation

arr_student->name
* * * * return;

}

I guess I have two questions before everyone dives into how wrong I
have done everything.
Q1. When I compile this I get the following error, could someone
please help explain why this occurs and how I can fix my code to
prevent this warning?
* * * * * *"test.c", line 25: warning: improper pointer/integer
combination: op "="
I'd have to compile your program to find out which line is
line 25. Couldn't you just tell us?
Q2. When I run my program, I am prompted with "Enter student name: "
and I enter in a name, I then receive the following error, can someone
please explain why this is happening too?
* * * * * *"Segmentation Fault"

I have a feeling I have declared my array of Student struct wrong
nope
and
I am also not passing the array through to the function correctly
which is causing both my problems.
I don't think you want an array...
>I have searched all over the
internet and in this discussion group but can't find an example
related to what I am trying to do.
<snip>
Below is my program:
you effectivly posted it twice...

<snip>
* * * * *arr_student[3].name = name;
3?
--
Nick Keighley

"The Dinosaurs have come and gone,
we Theriodonts remain"
Jun 27 '08 #4
On Thu, 01 May 2008 02:50:00 -0700, Nick Keighley wrote:
On 1 May, 02:41, "S." <sianeag...@gmail.comwrote:
>Â* Â* Â* Â* printf("%s",&students[0].name);

what's the & for?

students[0].name =char*
&students[0].name =char

oops! printf() is expecting a char* and you gave it a char
If students[0].name has type char*, then &students[0].name has type
char**. It's still wrong, of course.
Jun 27 '08 #5
S.
Hi all,

Thank you so much for your help. I have amended the code based on Jim
Langston's and Nick Keighley's comments. The specifics are as follows:
i. Changed the Student struct "name" variable from a pointer to a size
specified array - turned it into string array
ii. Changed the scanf to be: scanf("%s", arr_student->name )
ii. Renamed "arr_student" parameter of the addStudent function to
"student" because as Nick stated, this is not an array, but a student
being passed through

All errors appear resolved and there are no warnings. Program runs
squeaky.

Kind regards,
S.
Jun 27 '08 #6
S. wrote:
Hi all,

Thank you so much for your help. I have amended the code based on Jim
Langston's and Nick Keighley's comments. The specifics are as follows:
i. Changed the Student struct "name" variable from a pointer to a size
specified array - turned it into string array
ii. Changed the scanf to be: scanf("%s", arr_student->name )
ii. Renamed "arr_student" parameter of the addStudent function to
"student" because as Nick stated, this is not an array, but a student
being passed through

All errors appear resolved and there are no warnings. Program runs
squeaky.
For now. Try entering a name longer than the size you've allocated for
name. This produces undefined behavior.

You need to make sure that your data array doesn't get overflown
(overflowed?), which can happen here. I don't believe this can be done with
scanf though, you'll need to use some other input routine.

--
Jim Langston
ta*******@rocketmail.com
Jun 27 '08 #7
On Wed, 30 Apr 2008 18:41:40 -0700 (PDT), "S." <si********@gmail.com>
wrote:
>Hi all,

Can someone please help me with this?

I have the following struct:
typedef struct {
char *name;
int age;
} Student;
I have the following prototype declaration:
void addStudent(Student *arr_students);
The name of the parameter is not needed. However, if you use one it
should not be misleading like this one.
>
In my main, I want to have an array called 'students' which is
composed of the Student struct. I then want to pass a function that
will allow me to create a Student record using pass-by-reference:
In C, all argument passing and all return passing is done by value.
While passing an address has some similarities to pass by reference,
it is only some.
>int main() {
int main(void) is more precise.
>
Student students[CLASSSIZE]; /* array of student
struct's? */

addStudent(&students[0]);
printf("%s",&students[0].name);
return 0;
}

The following is my function to add a student:
void addStudent(Student *arr_student) {
char *name;

printf("\nEnter student name: ");
scanf("%s",&name);
*arr_student[0].name = name;
Since . binds more tightly than *, this is treated as
*(arr_student[0].name) = name;
What type is member name of your struct? What is the type when you
dereference this member? What is the type of the variable name? Are
these types compatible? Do you see the similarity between these two
types and the text of the error message?
>
return;
}

I guess I have two questions before everyone dives into how wrong I
have done everything.
Q1. When I compile this I get the following error, could someone
please help explain why this occurs and how I can fix my code to
prevent this warning?
"test.c", line 25: warning: improper pointer/integer
combination: op "="
Do not attempt to assign a pointer value to an integer variable.
>Q2. When I run my program, I am prompted with "Enter student name: "
and I enter in a name, I then receive the following error, can someone
please explain why this is happening too?
"Segmentation Fault"
You attempt to read character data into an area reserved for the value
of the name. You then try to pass this character data to printf as an
address. Character data usually does not form a good address. Once
printf tries to access the data at this wild address, you have entered
the realm of undefined behavior. A seg fault is one of the better
possible outcomes.
>
I have a feeling I have declared my array of Student struct wrong and
There is nothing wrong with your array definition.
>I am also not passing the array through to the function correctly
which is causing both my problems. I have searched all over the
You do not pass the array to the function at all. You do pass the
address of the first element of the array and you do that properly.
You have to make a design decision about how to process the other
elements of the array. One option would be to loop in main and pass
&students[i] instead of [0]. Another would be to have addStudent loop
through multiple elements by incrementing the pointer in each
iteration. (But then you should change the name to addStudents.)
>internet and in this discussion group but can't find an example
related to what I am trying to do.
You are biting off too much at one time. Forget the array of struct,
maybe even the struct itself. Start with a program that successfully
reads a name, stores it somewhere safely, and then prints it out (to
verify the first to steps). Then expand to store the name in a single
instance of the struct. Then expand to read the age and print both
members of the struct. Then start thinking about an array of struct.
>
Any help would be appreciated.

Kind regards,
S.

Below is my program:
We only need to see it once.
Remove del for email
Jun 27 '08 #8
On Thu, 1 May 2008 15:11:50 -0700, "Jim Langston"
<ta*******@rocketmail.comwrote:
S. wrote:
ii. Changed the scanf to be: scanf("%s", arr_student->name )
All errors appear resolved and there are no warnings. Program runs
squeaky.

For now. Try entering a name longer than the size you've allocated for
name. This produces undefined behavior.

You need to make sure that your data array doesn't get overflown
(overflowed?), which can happen here. I don't believe this can be done with
scanf though, you'll need to use some other input routine.
*scanf does allow input length limits, which for %s (and %[...] and
%c) translate directly into limits on the amount stored:
struct { ... char a [20]; ... } x; ...
if( scanf ("%19s", x.a) != 1 ) error;
/* 19 because %s or %[] stores a null terminator */

This is obviously a maintenance problem, and you can't automate it by
using the * modifier as you can for *printf. You can do either of:
- macro-stringize the limit, as a simple decimal constant only, into
the format, and use that same limit plus one to allocate the storage
- runtime-generate the format: can use sizeof(obj)-1 for the value.

Obviously these aren't ideal, and IMO&E are never the best solution to
this type of problem; but they are possible.

PS: 'overflowed' is correct. But you can avoid the issue by using
'overrun' instead: its participle is the same as its present.

- formerly david.thompson1 || achar(64) || worldnet.att.net
Jun 27 '08 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Dave A | last post by:
The following C code specifies the interface into a DLL. I need to access it from C#. How do I do declare it? I have done simple ones before but this particular API requires a pointer to a struct...
26
by: Dave Hammond | last post by:
In document "A.html" I have defined a function and within the document body have included an IFRAME element who's source is document "B.html". In document "B.html" I am trying to call the function...
33
by: Peter Seaman | last post by:
I understand that structures are value types and arrays and classes are reference types. But what about arrays as members of structures i.e. as in C struct x { int n; int a; }
5
by: Bern McCarty | last post by:
I have a DLL written in C++ (it's really C code that was adjusted to compile OK as C++) that I compile successfully into IL with the /CLR switch of Visual C 7.1. I use the resultant library...
10
by: David Fort | last post by:
Hi, I'm upgrading a VB6 app to VB.net and I'm having a problem with a call to a function provided in a DLL. The function takes the address of a structure which it will fill in with values. I...
64
by: Zytan | last post by:
I know there are no pointers in C#, but if you do: a = b; and a and b are both arrays, they now both point to the same memory (changing one changes the other). So, it makes them seem like...
29
by: Dom | last post by:
I'm really confused by the difference between a Struct and a Class? Sometimes, I want just a group of fields to go together. A Class without methods seems wrong, in that it carries too much...
9
by: Jack | last post by:
If I don't specify "ref" in the argument list when passing an array to the callee, I am passing the array (reference) by value. But this makes me confused because it actually means a "reference" of...
127
by: sanjay.vasudevan | last post by:
Why are the following declarations invalid in C? int f(); int f(); It would be great if anyone could also explain the design decision for such a language restricton. Regards, Sanjay
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.