Solved

implementation of a Structure in C language

Posted on 2009-05-17
9
1,350 Views
Last Modified: 2012-05-07
I recently tried something and i just want your take on it. here it is:

suppose you have a structure defined :

struct time{
             char name[10];
              char *lastname;
              };

typedef struct time T;

now, i have to write the following functions:

initialise();
copyTIme(); //deep copy
deleteTIme();
printTIme();

so, here is my version:

T initialise(T *time, char name, char lastname)
{
  time->name= 0;
  time->lastname = malloc(sizeof(char));
}

T copy(T *time, char name, char lastname){
 T*time2;
 T*time2 = malloc(sizeof(T));
 strcpy(time2->name, time->name);
 strcpy(time2->lastname, time->lastname);
 deleteTIme(&time);
 return time2;
 
}

void deleteTIme(T*time){
free time->lastname;
free time;
}

void printTIme(T time){
printf(time.name);
printf(time.lastname);
}

those are my versions. well, let me know if my reasoning was ok and also, i read in the book that to copy the structure, i need to do the deep copy which is what i have implemented but i want to know why?
expecting your reply soon.
 

 


0
Comment
Question by:admindesk
  • 5
  • 4
9 Comments
 
LVL 53

Expert Comment

by:Infinity08
ID: 24406878
>> T initialise(T *time, char name, char lastname)

char only holds one character. You want a string of characters, so a char*, or better yet a const char*, since you don't intend to modify them inside the function.


>>   time->name= 0;

You can't assign 0 to an array. Use strncpy if you want to copy a string to another :

    http://cplusplus.com/reference/clibrary/cstring/strncpy/


>>   time->lastname = malloc(sizeof(char));

That only allocates room for one char. You want enough room for all characters of the last name + one more for the terminating '\0' character.


>> T copy(T *time, char name, char lastname){

I assume you meant to return a T*, instead of a T.


>>  T*time2;
>>  T*time2 = malloc(sizeof(T));

You declared time2 twice. Once is enough ;)


>>  strcpy(time2->lastname, time->lastname);

You need to allocate memory for time2->lastname before you copy something to it. Make sure there's enough room for the whole string (including the terminating '\0' character).


>>  deleteTIme(&time);

Why do you do that inside the copy function ? It's a copy function, not a move function. That means you still need both copies after the function ends.


>> free time->lastname;
>> free time;

free is a function, so you need to pass its parameter using ()'s.


>> void printTIme(T time){

I assume you meant to pass a T* as argument, not a T.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 24406883
>> i need to do the deep copy which is what i have implemented but i want to know why?

A deep copy ensures that both copies are independent. Meaning that if one of them is deleted, the other one is still valid. With a shallow copy (where pointers are simply copied), deleting one of the copies would make that the other copy's lastname field no longer points to allocated memory.
0
 

Author Comment

by:admindesk
ID: 24409006
Helllo,

i actually dont want a string of characters. it's just a structure that holds a person's name which must not be more than 10 characters per name and his lastname which has been declared as a pointer.

>> T initialise(T *time, char name, char lastname)
{
   so would i be correct if i do this:
for (i = 0; i<10;i++)
 time->name = 0;
time->lastname = malloc(sizeof(char)); //just want to allocate space for character to my lastname

ok for the T copy function here is my modification:

T *copy(T *time, char name, char lastname){

 T*time2 = malloc(sizeof(T));
 strcpy(time2->name, time->name);
 strcpy(time2->lastname, time->lastname);
 deleteTIme(&time); //if you think i am wrong deleting the previous structure, how do i delete it then?
 return time2;
}

and is the delete function ok now?

void deleteTIme(T*time){
free( time->lastname);
free (time);
}

finally, i am not passing a pointer in the print function just wanted to pass the time variable that way but it's ok if i pass pointers:
void printTIme(T *time){
printf(time->name);
printf(time->lastname);
}

what difference does it makes with the initial one?

question 2:

back to the reason why the deep copy is necessary, was it because i had one of the variable declared as a pointer ? i mean the char *lastname? and if it is so, could you draw a small picture of how these deep copy is implemented and what would have happened if it wasn't done. i am trying to figure out a pictorial diagram of the scenario.

thanks.

0
Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

 
LVL 53

Accepted Solution

by:
Infinity08 earned 500 total points
ID: 24409233
>> i actually dont want a string of characters.

>> it's just a structure that holds a person's name which must not be more than 10 characters

You're contradicting yourself here. You want to store a name with a maximum of 10 characters, but you don't want to use a character string for that ? That doesn't make sense. Your struct definition (although inconsistent) was correct :

>> struct time{
>>              char name[10];
>>               char *lastname;
>>               };

You have to make sure that the rest of the code matches that definition. ie. name is a member string of 9 characters, and lastname is a member pointer to a string of characters.


>> for (i = 0; i<10;i++)
>>  time->name = 0;

Now you're just assigning 0 to an array 10 times instead of once ... That doesn't change anything. You can't assign an integer value to an array. The types are incompatible. Use strncpy if you want to copy the function argument in there. If you want to do something else, then please explain what.


>> time->lastname = malloc(sizeof(char)); //just want to allocate space for character to my lastname

I'm pretty sure you DON'T just want to allocate space for ONE character. A one character last name doesn't make much sense, does it ?


>> T *copy(T *time, char name, char lastname){

Again : use char*, not char. char is a single character only. That's not enough to store a name.


>>  strcpy(time2->lastname, time->lastname);

in the copy function, you need to allocate memory for time2->lastname first before you copy data into it (as I said earlier).


>>  deleteTIme(&time); //if you think i am wrong deleting the previous structure, how do i delete it then?

You don't :) Why should you have to delete it ?


>> and is the delete function ok now?

Yes :)


>> finally, i am not passing a pointer in the print function just wanted to pass the time variable that way but it's ok if i pass pointers:

It's better to pass a pointer, especially if the structure gets bigger. Otherwise, you'd have to make a copy of the entire struct each time you call the print function.


>> back to the reason why the deep copy is necessary, was it because i had one of the variable declared as a pointer ?

Indeed.


>> and if it is so, could you draw a small picture of how these deep copy is implemented and what would have happened if it wasn't done.

A shallow copy copies only the pointer value to the new structure ... It doesn't copy the actual data that pointer is pointing to. So, the new structure will contain a pointer that points to the SAME data as the original structure. If you modify that data in the original structure, it will also be modified for the new structure. If you delete that data in the original structure, it will also be deleted for the new structure.
A deep copy copies the data that the pointer points to to the new structure. So, both the original and the new structures have their own copy of the data. If the data is modified or deleted in the original structure, that won't have an impact on the new structure (and vice versa).


I have the impression that you have some trouble getting your head around character strings. I suggest reading this tutorial :

        http://cplusplus.com/doc/tutorial/ntcs/

(it's written for C++, but just ignore the C++ specific parts ;) )
0
 

Author Comment

by:admindesk
ID: 24418776
helllo i get what you mean, i will get back to you say in another 20 hours because i will be very busy today but soon as i am free i will come running to learn from you more. this is interesting. i will have to go through that again. one quick thing i thought about the initialise function is that if i have to allocate memory for a pointer to a pointer (char *lastname) that means there has to be an amount of characters the character string lastname must contain. just like i have done for the firstname. so, that means i will be declaring an extra variable say N to store the max number i guess?
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 24418932
>> if i have to allocate memory for a pointer to a pointer (char *lastname)

lastname is not a pointer-to-pointer. It's a pointer-to-char, more commonly called a C string.


>> that means there has to be an amount of characters the character string lastname must contain. just like i have done for the firstname. so, that means i will be declaring an extra variable say N to store the max number i guess?

No. You can allocate the precise amount needed for the current last name. The initialize function takes a C string (char*) as parameter, so you can use strlen to get the length of that string, add 1 to it (for the terminating '\0' character), and allocate that amount of memory.

    http://cplusplus.com/reference/clibrary/cstring/strlen/
0
 

Author Comment

by:admindesk
ID: 24424276
Hello,

but it's still a pointer and one has to allocate space for it. so what if i do this:

time->lastname = malloc(sizeof(char))+1;?

pls let me know.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 24424762
>> but it's still a pointer and one has to allocate space for it.

Yes it is, and yes you have to allocate space for it.


>> time->lastname = malloc(sizeof(char))+1;?

Did you understand the remarks I made earlier about how many characters you need to allocate room for ? One char is not enough for a string, and the +1 after it shouldn't be there.

It seems you still have trouble with C strings ... Did you read and understand the tutorial I posted earlier ?
0
 

Author Comment

by:admindesk
ID: 24459661
hello, ok let me read the tutorial first.

thanks all the same.
0

Featured Post

Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
undefined reference to `bswap_128' 9 176
TCP/IP Socket - connection close results in data lost 14 142
Problem to save 10 174
windows 10 pro lost profile. 10 46
An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.

820 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question