473,785 Members | 2,291 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Allocate memory to char * variables in structure

Hi,

I have a homework project I am working on, so be forwarned, I'm new to
C programming. But anyway, having some trouble with a memory
allocation issue related to a char * that is a variable inside of a
structure. I keep getting segmentation fault errors and I am having
trouble understanding why. Here's the parts of the code in question...

This is part of the .h file where the struct us defined...

enum color { COLORS };
typedef enum color Color;

struct person
{
char *firstName;
char *lastName;
char *hobby;
Color favColor;
char sex;
int age;
};
typedef struct person Person;

struct node
{
struct node *next;
Person client;
};
typedef struct node Node;

Now here is the function that I am having trouble with... If you look
down to the section where this line is found...

member->firstName = (char *)calloc(strlen (fname)+1, sizeof(char));

The compiler stops there and generates the seg fault message. Here's
the full function. By the way I have tested the first part of the
function, the file pointer exists and the output to stdout from printf
is working ok until I get the line above. Then the program crashes.

Am I trying to allocate the memory in the wrong way?
Person *createMember(F ILE *infile)
{
char fname[30];
char lname[30];
char sex[10];
char age[10];
char color[20];
char hobby[30];
char *colorS;
Person *member;

if (!feof(infile))
{
fgets(fname, 30, infile);
fgets(lname, 30, infile);
fgets(sex, 10, infile);
fgets(age, 10, infile);
fgets(color, 20, infile);
fgets(hobby, 30, infile);
}

else
return NULL;
printf("top of createMember\n" );
/* read member attributes from file */
fgets(fname, sizeof fname, infile);
fname[strlen(fname)-1] = '\0';
fgets(lname, sizeof lname, infile);
lname[strlen(lname)-1] = '\0';
fgets(sex, sizeof sex, infile);
sex[strlen(sex)-1] = '\0';
fgets(age, sizeof age, infile);
age[strlen(age)-1] ='\0';
fgets(color, sizeof color, infile);
color[strlen(color)-1] = '\0';
fgets(hobby, sizeof hobby, infile);
hobby[strlen(hobby)-1] = '\0';
printf("got through fgets statements.\n") ;

/* create memory allocation for member attributes */
member->firstName = (char *)calloc(strlen (fname)+1, sizeof(char));
printf("calloc firstName\n");
member->lastName = (char *)malloc(sizeof (fname) * sizeof(char));
member->hobby = (char *)malloc(sizeof (hobby) * sizeof(char));
colorS = (char *)malloc(sizeof (color) * sizeof(char));
printf("got past malloc statements\n");

/* store member attributes */
strcpy(member->firstName, fname);
printf("fname processed\n");
sscanf(lname, "%s", member->lastName);
sscanf(sex, "%c", member->sex);
sscanf(age, "%d", member->age);
strncpy(colorS, color, sizeof(color));
member->favColor = readColor(color S);
sscanf(hobby, "%s", member->hobby);
printf("bottom of createMember\n" );

return member;
}

David

Mar 5 '07
17 9149
santosh wrote, On 05/03/07 06:04:
dt*******@gmail .com wrote:
<snip>
> /* create memory allocation for member attributes */
member->firstName = (char *)calloc(strlen (fname)+1, sizeof(char));

Here's your main error. member is pointer to a Person type, (which is
actually a struct of type person), but as yet it doesn't point to
valid instance of a Person object. You need to define a Person object,
set member to point to it and then do the memory allocation for the
fields like:

Person p1;
member = &p1;
<snip>

You might confuse the OP my showing this method.
> return member;
}

Make sure your Person object is not a local one, since, if so, it'll
get destroyed when execution leaves this function. Either dynamically
allocate the object or make it a file scope one.
Making it file scope is incredibly bad advice, please don't suggest to
newbies using "globals", they are needed sometimes, but definitely not
in most situations where a newbie might use them. Making it a static
(which would also would) would be bad advice as well.

Either it should be dynamically allocated or a pointer to a structure
provided by the calling routine should be passed in, depending on
exactly what the OP is doing.
--
Flash Gordon
Mar 5 '07 #11
dt*******@gmail .com wrote, On 05/03/07 05:35:
>
I have a homework project I am working on,
Thank you for being honest about it being homework.
so be forwarned, I'm new to
C programming. But anyway, having some trouble with a memory
allocation issue related to a char * that is a variable inside of a
structure. I keep getting segmentation fault errors and I am having
trouble understanding why. Here's the parts of the code in question...

This is part of the .h file where the struct us defined...

enum color { COLORS };
typedef enum color Color;

struct person
{
char *firstName;
char *lastName;
char *hobby;
Color favColor;
char sex;
int age;
};
typedef struct person Person;

struct node
{
struct node *next;
Person client;
};
typedef struct node Node;

Now here is the function that I am having trouble with... If you look
down to the section where this line is found...

member->firstName = (char *)calloc(strlen (fname)+1, sizeof(char));
Firstly you do not need to cast the result of calloc/malloc/realloc. If
the compiler complains without the cast then that means you have done
something else wrong, either compiling the code as C++ (where the cast
would be needed but you should not really use malloc) or failing to
#include <stdlib,h>
>
The compiler stops there and generates the seg fault message. Here's
I don't think it is the compiler that is stopping with a seg fault,
rather it is your program stopping with a seg fault when you run it.
This is a very important distinction since the compiler seg faulting
would mean either a compiler bug or a hardware fault rather than a bug
in your program.

Precision is important in programming and in reporting problems.
the full function. By the way I have tested the first part of the
function, the file pointer exists and the output to stdout from printf
is working ok until I get the line above. Then the program crashes.

Am I trying to allocate the memory in the wrong way?
Yes, but not quite wrong in the way you think.
Person *createMember(F ILE *infile)
{
char fname[30];
char lname[30];
char sex[10];
char age[10];
char color[20];
char hobby[30];
char *colorS;
Person *member;
member is a pointer to a struct, but currently it does not point anywhere.
if (!feof(infile))
This is almost certainly incorrect use of feof. In C feof does not tell
you that you are at the end of the file, it tells you if your failure to
read from the file was due to being at the end of file. I.e. it only
helps after the event, not before.
{
fgets(fname, 30, infile);
fgets(lname, 30, infile);
fgets(sex, 10, infile);
fgets(age, 10, infile);
fgets(color, 20, infile);
fgets(hobby, 30, infile);
You should check whether any of the above fail. One possible "simple"
method would be getting rid of the if above and using:
if (!(fgets(...) &&
fgets(...) && ... )
return NULL;

This relies on:
1) fgets is defined as returning a null pointer on failure doe to either
EOF or some other error condition and a non-null pointer otherwise
2) A null pointer in a boolean context is treated as "false" and a
non-null pointer as "true"
3) It saves needless calls to fgets because as soon as one fails the
"short-circuit" rules of && will means that the rest are not done.

All of the above are guaranteed by the C standard.
}

else
return NULL;
printf("top of createMember\n" );
/* read member attributes from file */
fgets(fname, sizeof fname, infile);
Why are you reading over fname again? Where is your error checking?
fname[strlen(fname)-1] = '\0';
What if the line was too long? You need to check that as well.
fgets(lname, sizeof lname, infile);
lname[strlen(lname)-1] = '\0';
fgets(sex, sizeof sex, infile);
sex[strlen(sex)-1] = '\0';
fgets(age, sizeof age, infile);
age[strlen(age)-1] ='\0';
fgets(color, sizeof color, infile);
color[strlen(color)-1] = '\0';
fgets(hobby, sizeof hobby, infile);
hobby[strlen(hobby)-1] = '\0';
printf("got through fgets statements.\n") ;

/* create memory allocation for member attributes */
member->firstName = (char *)calloc(strlen (fname)+1, sizeof(char));
Remember I said that member did not point anywhere yet? Well, it still
does not. You need to allocate space for your struct and assign the
pointer to that space to member first.

You also need to check if malloc/calloc/realloc failed.

Finally, since you are about to write a string in to the allocated space
there is no point using calloc, you might as well use malloc.
printf("calloc firstName\n");
member->lastName = (char *)malloc(sizeof (fname) * sizeof(char));
member->hobby = (char *)malloc(sizeof (hobby) * sizeof(char));
colorS = (char *)malloc(sizeof (color) * sizeof(char));
printf("got past malloc statements\n");

/* store member attributes */
strcpy(member->firstName, fname);
printf("fname processed\n");
sscanf(lname, "%s", member->lastName);
sscanf(sex, "%c", member->sex);
sscanf(age, "%d", member->age);
The above calls to sscanf are wrong, and in any case you do not need the
flexibility of sscanf. Read up on scanf, and also on the strto*
functions and remember that a string is an array of characters so you
can access an individual character using array access.
strncpy(colorS, color, sizeof(color));
ColorS does not point anywhere yet so this is a problem. In any case,
strncpy is almost certainly not what you want.
member->favColor = readColor(color S);
sscanf(hobby, "%s", member->hobby);
printf("bottom of createMember\n" );

return member;
}
I suggest you read the comp.lang.c FAQ at http://c-faq.com/
Start with sections 6, 7 and 12 which address some of your
misconceptions, then go through the rest as and when you have time. Also
keep it bookmarked as you should go back to it to look for solutions to
your problems before posting here. If you can't find, or can't
understand, the answer then ask for help.
--
Flash Gordon
Mar 5 '07 #12
Flash Gordon wrote:
santosh wrote, On 05/03/07 06:04:
dt*******@gmail .com wrote:

<snip>
/* create memory allocation for member attributes */
member->firstName = (char *)calloc(strlen (fname)+1, sizeof(char));
Here's your main error. member is pointer to a Person type, (which is
actually a struct of type person), but as yet it doesn't point to
valid instance of a Person object. You need to define a Person object,
set member to point to it and then do the memory allocation for the
fields like:

Person p1;
member = &p1;

<snip>

You might confuse the OP my showing this method.
Why?
return member;
}
Make sure your Person object is not a local one, since, if so, it'll
get destroyed when execution leaves this function. Either dynamically
allocate the object or make it a file scope one.

Making it file scope is incredibly bad advice, please don't suggest to
newbies using "globals", they are needed sometimes, but definitely not
in most situations where a newbie might use them. Making it a static
(which would also would) would be bad advice as well.
Point taken.

Mar 5 '07 #13
"dt*******@gmai l.com" wrote:
On Mar 4, 10:04 pm, "santosh" <santosh....@gm ail.comwrote:
>Why are you overwriting fname again?
>> fname[strlen(fname)-1] = '\0';

This will already be done for you by fgets.

Well, according to my handy dandy textbook, Programming in C by
Stephen Kochan, the fgets function will read everything into the
array including the newline character (\n), so I am overwriting
the newline character with the \0 character so I can eliminate
the newline character.

I am reading all the data from a file and each set of data ends
with new line character.
But you don't handle the case where those lines are overlong. This
is an ideal place to use ggets (but not gets), which will handle
allocation and consistently suppress the terminal '\n'. You can
find it at:

<http://cbfalconer.home .att.net/download/>

--
<http://www.cs.auckland .ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfoc us.com/columnists/423>

"A man who is right every time is not likely to do very much."
-- Francis Crick, co-discover of DNA
"There is nothing more amazing than stupidity in action."
-- Thomas Matthews

Mar 5 '07 #14
santosh wrote, On 05/03/07 08:12:
Flash Gordon wrote:
>santosh wrote, On 05/03/07 06:04:
>>dt*******@gmail .com wrote:
<snip>
>>> /* create memory allocation for member attributes */
member->firstName = (char *)calloc(strlen (fname)+1, sizeof(char));
Here's your main error. member is pointer to a Person type, (which is
actually a struct of type person), but as yet it doesn't point to
valid instance of a Person object. You need to define a Person object,
set member to point to it and then do the memory allocation for the
fields like:

Person p1;
member = &p1;
<snip>

You might confuse the OP my showing this method.

Why?
<snip>

Because it is not the correct solution to the problem as you correctly
stated further down but at this point in the post (and for a fair bit
their after) the OP would probably be assuming that it was the correct
solution.

My experience with inexperienced people is that if you present an
incorrect solution and then a fair time later get around to saying it is
incorrect you confuse them, since they have been assuming it to be the
correct solution to their problem.
--
Flash Gordon
Mar 5 '07 #15
At about the time of 3/4/2007 9:35 PM, dt*******@gmail .com stated the
following:
Hi,

I have a homework project I am working on, so be forwarned, I'm new to
C programming. But anyway, having some trouble with a memory
allocation issue related to a char * that is a variable inside of a
structure. I keep getting segmentation fault errors and I am having
trouble understanding why. Here's the parts of the code in question...

This is part of the .h file where the struct us defined...

enum color { COLORS };
typedef enum color Color;

struct person
{
char *firstName;
char *lastName;
char *hobby;
Color favColor;
char sex;
int age;
};
typedef struct person Person;

struct node
{
struct node *next;
Person client;
};
typedef struct node Node;

Now here is the function that I am having trouble with... If you look
down to the section where this line is found...

member->firstName = (char *)calloc(strlen (fname)+1, sizeof(char));

The compiler stops there and generates the seg fault message. Here's
the full function. By the way I have tested the first part of the
function, the file pointer exists and the output to stdout from printf
is working ok until I get the line above. Then the program crashes.

Am I trying to allocate the memory in the wrong way?

Yep. Just use malloc(3).
Person *createMember(F ILE *infile)
{
char fname[30];
char lname[30];
char sex[10];
char age[10];
char color[20];
char hobby[30];
char *colorS;
Person *member;

if (!feof(infile))
{
fgets(fname, 30, infile);
fgets(lname, 30, infile);
fgets(sex, 10, infile);
fgets(age, 10, infile);
fgets(color, 20, infile);
fgets(hobby, 30, infile);
}

else
return NULL;
printf("top of createMember\n" );
/* read member attributes from file */
fgets(fname, sizeof fname, infile);
fname[strlen(fname)-1] = '\0';
fgets(lname, sizeof lname, infile);
lname[strlen(lname)-1] = '\0';
fgets(sex, sizeof sex, infile);
sex[strlen(sex)-1] = '\0';
fgets(age, sizeof age, infile);
age[strlen(age)-1] ='\0';
fgets(color, sizeof color, infile);
color[strlen(color)-1] = '\0';
fgets(hobby, sizeof hobby, infile);
hobby[strlen(hobby)-1] = '\0';
printf("got through fgets statements.\n") ;

/* create memory allocation for member attributes */
member->firstName = (char *)calloc(strlen (fname)+1, sizeof(char));
printf("calloc firstName\n");
member->lastName = (char *)malloc(sizeof (fname) * sizeof(char));
member->hobby = (char *)malloc(sizeof (hobby) * sizeof(char));
colorS = (char *)malloc(sizeof (color) * sizeof(char));
printf("got past malloc statements\n");

/* store member attributes */
strcpy(member->firstName, fname);
printf("fname processed\n");
sscanf(lname, "%s", member->lastName);
sscanf(sex, "%c", member->sex);
sscanf(age, "%d", member->age);
strncpy(colorS, color, sizeof(color));
member->favColor = readColor(color S);
sscanf(hobby, "%s", member->hobby);
printf("bottom of createMember\n" );

return member;
}

David
Your statements like malloc(sizeof(f name) * sizeof(char)); can be
reduced to malloc(sizeof(f name)); since char is garunteed to be size 1.

--
Daniel Rudy

Email address has been base64 encoded to reduce spam
Decode email address using b64decode or uudecode -m

Why geeks like computers: look chat date touch grep make unzip
strip view finger mount fcsk more fcsk yes spray umount sleep
Mar 5 '07 #16
On Mar 5, 1:19 am, CBFalconer <cbfalco...@yah oo.comwrote:
"dtscho...@gmai l.com" wrote:
On Mar 4, 10:04 pm, "santosh" <santosh....@gm ail.comwrote:
Why are you overwriting fname again?
> fname[strlen(fname)-1] = '\0';
This will already be done for you by fgets.
Well, according to my handy dandy textbook, Programming in C by
Stephen Kochan, the fgets function will read everything into the
array including the newline character (\n), so I am overwriting
the newline character with the \0 character so I can eliminate
the newline character.
I am reading all the data from a file and each set of data ends
with new line character.

But you don't handle the case where those lines are overlong. This
is an ideal place to use ggets (but not gets), which will handle
allocation and consistently suppress the terminal '\n'. You can
find it at:

<http://cbfalconer.home .att.net/download/>

--
In this case the instructor is guaranteeing our input will meet
certain specifications. I agree normally I would need to check for
oversized input.

David
Mar 6 '07 #17
dt*******@gmail .com wrote, On 06/03/07 05:45:

<snip>
In this case the instructor is guaranteeing our input will meet
certain specifications. I agree normally I would need to check for
oversized input.
My experience is that whenever one is given such a guarantee you end up
receiving input that through some error does not meet the specification.
Therefore it is best to at least do a check a check and some rudimentary
handling of bad data. As this is just homework, something as simple as
aborting the program with a suitable error message if the data is out of
spec would do. You might even get extra points for it!
--
Flash Gordon
Mar 6 '07 #18

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

Similar topics

37
4682
by: Curt | last post by:
If this is the complete program (ie, the address of the const is never taken, only its value used) is it likely the compiler will allocate ram for constantA or constantB? Or simply substitute the values in (as would be required if I used the hideous, evil, much-abused #define :) ----------- const int constantA = 10; static const int constantB = 20;
5
2484
by: lixiaoyao | last post by:
hi all I use matrix & vector function to allocate the space myself in c, typedef struct matrix_array newdata; struct matrix_array{ float **sy,*sxx; }; newdata ndata;//new data struct ndata.sy=matrix(1,nvar,1,nstep); ndata.sxx=vector(1,nstep);
12
5638
by: gc | last post by:
I am writing a function that given nx1 vector a and a nx1 b solves a system of equations f(a,c)=b for a nx1 c. While writing the function: 1] Should I allocate the memory for c within the function and return the allocated memory? something that leads to double *solve(const double *a,const double *b,int n) { double *c;
8
2934
by: vikram | last post by:
i have series of questions 1.How a c program is loaded in memory i mean the whats is the structure that the code segment?? data segment?? 2.When you say const int *p; where is p stored in the memory?? what happens internal so that its a read only. 3. when declared volatile int *p where exactly in the memory it is stored.
9
1956
by: Alfonso Morra | last post by:
Hi, I am having some probs with copying memory blocks around (part of a messaging library) and I would like some confirmation to make sure that I'm going about things the right way. I have some data types defined thus: typedef enum { ONE ,
2
11954
by: vikas | last post by:
I have following structure in c++. typedef struct MMF_result_struct { int action; char text; int cols,rows; int month,day,year; } MMF_result; Now this structure is shared between C++ and C# using memory mapped file. We already have C++ code for handling memory mapped file. I am working on converting code for memory mapped file in C#. Now I have to pass pointer to the above structure. I converted this structure to C# as follows:
14
2642
by: raghu | last post by:
Hello , This is Raghu. I have a problem in declaring a structure. Consider struct hai{ int id; char sex; int age; }; here when a variable is instianted for this structure then immediately
5
1789
by: raghu | last post by:
Hello , This is Raghu. I have a problem in declaring a structure. Consider struct hai{ int id; char sex; int age; }; here when a variable is instianted for this structure then immediately
1
2591
by: sunil | last post by:
Hi, Am developing one shared library for one application. In that .so am having one global array of structure ( two more different structure pointers in this struct). Once the application is launched, then I am allocating the memory on the heap for the internal structures. To print the log messages I am using the below mentioned global variables and time header functions.
0
9647
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10163
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9959
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8988
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7510
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6744
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5397
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4063
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2894
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.