LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 08-18-2019, 10:21 AM   #166
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth? I would say I hope so but I'm not so sure about that... I could just be a figment of your imagination too.
Distribution: Currently OpenMandriva. Previously openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,085

Original Poster
Rep: Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595

Quote:
Originally Posted by ntubski View Post
Could that be a due to a difference in tab size?
Quote:
Originally Posted by rtmistler View Post
Or perhaps the presence of tabs entirely. I suggest to never use TABS, except in a Makefile where they are required, or any other particular file similar in nature. C source files, I feel should all contain spaces as opposed to tabs.

Just my humble opinion.
I was using spaces, not tabs. All I know is the since I changed distro's, it's been happening - but wasn't before. In CentOS 7 (my old distro) I was using KDE 4, but OpenMandriva Lx 4.0 (the distro I'm using now) uses KDE 5 - therefore before KWrite was the 4.x series (KDE Applications 4.x series), but now I've got the 5.x series of KWrite (KDE Applications 5.x series).

Quote:
And sorry once again for posting code, which was not compiled, just typed off the cuff. Obviously caused a bit of confusion there.
That's ok RT, I still learnt something, and at least I know how to deal with nested structures now. So your post was still quite useful - particularly in relation to pointers. Speaking of which...

I wrote another version of the same structures I posted before, this time using a pointer so I could use the structure pointer operator. It compiles without any warnings or errors, and does the same thing as before. So your post RT was how I figured out how to add the pointer and use the structure pointer operator.

Here's the code;

Code:
#include <stdio.h>

int main(void) {

    struct date {
        int day;
        int month;
        int year;
        struct time *timePtr;
        struct time {
            int hour;
            int minute;
            int seconds;
        } now;
    };

    struct date today;
    struct time now;
    
    today.timePtr = &now;
           
    today.day = 18;
    today.month = 8;
    today.year = 2019;
    today.timePtr->hour = 1;
    today.timePtr->minute = 51;
    today.timePtr->seconds =  32;

    printf("Date and time is: %i/%i/%i %i:%i:%i\n", today.day, today.month, today.year, today.timePtr->hour, today.timePtr->minute, today.timePtr->seconds);

    return 0;
}
But for some reason, if I comment out the following line, gcc will still complain when trying to compile it - even though "now" is already declared before it. So donno what's going on there.

Code:
struct time now;
This is the result;

Code:
james@jamespc: devel> ./nested_struct_ptr 
Date and time is: 18/8/2019 1:51:32
Thanks again!
 
Old 08-18-2019, 11:13 AM   #167
rtmistler
Moderator
 
Registered: Mar 2011
Location: MA, USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 8,054
Blog Entries: 13

Rep: Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501
I have a suspicion, but I'm not exactly sure.

Meanwhile this seems a great opportunity to use, yes my favorite, GDB and examine the structure, the pointer it contains, and determine exactly what it is pointing to.
 
2 members found this post helpful.
Old 08-18-2019, 11:30 AM   #168
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,509

Rep: Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811Reputation: 1811
Quote:
Originally Posted by jsbjsb001 View Post
But for some reason, if I comment out the following line, gcc will still complain when trying to compile it - even though "now" is already declared before it. So donno what's going on there.

Code:
struct time now;
No, after removing that line, "now" is only defined as a field in struct date values. There isn't any "now" variable, just like there aren't any "day" or "month" variables.
 
2 members found this post helpful.
Old 08-18-2019, 01:18 PM   #169
Mechanikx
Member
 
Registered: Jul 2018
Location: Canada
Distribution: Slackware
Posts: 182

Rep: Reputation: 145Reputation: 145
Just adding to ntubski's and rtmistler's replies:

All you need is this line:

Quote:
struct date today;
and after this line all memory will now have been allocated for the entire structure including the nested time structure.

What is happening here is you have created a separate time structure called 'now' with this line:

Quote:
struct time now;
and THAT is what 'today.timePtr' is pointing to:

Quote:
today.timePtr = &now;
So when you comment out this line "struct time now;" you will get an error because now 'now' won't exist but 'today.now' still does because it was already defined.

If the pointer 'today.timePtr' is meant to point to the 'now' member of the time structure, then you would do this:

Quote:
today.timePtr = &today.now;
How the code currently is you are assigning values to the time structure 'now' NOT the 'now' member of the today structure. Add this line to the code after the rest of the printf statements:

Quote:
printf("%i\n", today.now.minute);
and you will see it prints a garbage value because nothing has been assigned to it. If you make the changes I mentioned your values will get assigned to the 'today.now' members and the program will print those values.

Last edited by Mechanikx; 08-18-2019 at 02:54 PM. Reason: Clarified.
 
1 members found this post helpful.
Old 08-19-2019, 01:22 AM   #170
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth? I would say I hope so but I'm not so sure about that... I could just be a figment of your imagination too.
Distribution: Currently OpenMandriva. Previously openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,085

Original Poster
Rep: Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595
Thanks guys, and thank you to ntubski and Mechanikx for explaining that! As that's what I was misunderstanding.

So I did what you said Mechanikx which fixed it, and like RT, and ntubski; you are very good at explaining things too! I wanted to get ya's more rep, but the bloody reputation system keeps blocking my attempts to do that - but I would've if I could've.

So first I tried to print what I was actually trying to point the pointer to, which is indeed the "time" structure within the "date" structure. Then I got rid of the "struct time now;" line and changed the "today.timePtr = &now;" line to "today.timePtr = &today.now;", and also added the line below the first printf "printf("today.now.hour = %i\n", today.now.hour);" (the rest of the code is the same as above tho), which prints the correct results.

Code:
james@jamespc: devel> gcc -g -Wall -Werror nested_struct_ptr.c -o nested_struct_ptr
nested_struct_ptr.c: In function ‘main’:
nested_struct_ptr.c:30:5: error: ‘today.now.hour’ is used uninitialized in this function [-Werror=uninitialized]
   30 |     printf("today.now.hour = %i\n", today.now.hour);
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
james@jamespc: devel> gcc nested_struct_ptr.c -o nested_struct_ptr
james@jamespc: devel> ./nested_struct_ptr 
Date and time is: 18/8/2019 1:51:32
today.now.hour = 4195440
james@jamespc: devel> gcc -g -Wall -Werror nested_struct_ptr.c -o nested_struct_ptr
james@jamespc: devel> ./nested_struct_ptr 
Date and time is: 18/8/2019 1:51:32
today.now.hour = 1
Thanks again guys

Also, I wanted to ask you RT about this comment you made:

Quote:
Originally Posted by rtmistler View Post
...
Aside: What I DON'T like is that they are using THAT as a passing argument. Use pointers instead. Structures can be huge in size. Eating stack.
While I think I get what you mean about structures could be huge in size; what exactly do you mean about using pointers instead beyond the obvious? Like for example; how would I use pointers to avoid blowing up the stack? As while I sorta get what the stack is; I can't say I fully understand how it works yet. So if you could explain that a bit more (and perhaps an example of what you mean), that would be helpful, if you would be so kind.
 
1 members found this post helpful.
Old 08-19-2019, 05:47 AM   #171
rtmistler
Moderator
 
Registered: Mar 2011
Location: MA, USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 8,054
Blog Entries: 13

Rep: Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501
Function passing arguments use your stack.

The more or larger they are, the more stack you're using.

It's not illegal, but I'd not recommend it.
 
1 members found this post helpful.
Old 08-19-2019, 08:12 AM   #172
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth? I would say I hope so but I'm not so sure about that... I could just be a figment of your imagination too.
Distribution: Currently OpenMandriva. Previously openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,085

Original Poster
Rep: Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595
Quote:
Originally Posted by rtmistler View Post
Function passing arguments use your stack.

The more or larger they are, the more stack you're using.

It's not illegal, but I'd not recommend it.
I understand what you're saying, but I'm still not clear exactly what you mean when you say "use pointers instead". Could you explain what I'm missing there? Like; how exactly would I use pointers so I'm not "eating the stack"? As I'm honestly just not clear on what exactly you mean there, let alone how I would go about taking your advice. Could you give an example so I can see what you mean? Can you give an example of how I would use pointers to avoid "eating the stack"? Because without an example and more context, I really don't know what to make of your comment beyond what's already been said.
 
Old 08-19-2019, 09:42 AM   #173
rtmistler
Moderator
 
Registered: Mar 2011
Location: MA, USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 8,054
Blog Entries: 13

Rep: Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501
Quote:
Originally Posted by jsbjsb001 View Post
I understand what you're saying, but I'm still not clear exactly what you mean when you say "use pointers instead". Could you explain what I'm missing there? Like; how exactly would I use pointers so I'm not "eating the stack"? As I'm honestly just not clear on what exactly you mean there, let alone how I would go about taking your advice. Could you give an example so I can see what you mean? Can you give an example of how I would use pointers to avoid "eating the stack"? Because without an example and more context, I really don't know what to make of your comment beyond what's already been said.
Don't write any more code to figure this out.

Use your mind to think about it.

If you consider a structure. Just estimate how many bytes it takes up. Like the one you've been using. How many bytes does that up in space?

Now, consider a pointer. How many bytes of space does that take up? Just the pointer, not what it's pointing at.
 
Old 08-19-2019, 09:48 AM   #174
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth? I would say I hope so but I'm not so sure about that... I could just be a figment of your imagination too.
Distribution: Currently OpenMandriva. Previously openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,085

Original Poster
Rep: Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595
So you're saying that I would setup a pointer to point to the structure, and pass the pointer (that's pointing to the structure) as an argument for the function, instead of passing the actual structure as an argument for the function?
 
Old 08-19-2019, 09:58 AM   #175
GazL
LQ Guru
 
Registered: May 2008
Posts: 5,187
Blog Entries: 18

Rep: Reputation: 2902Reputation: 2902Reputation: 2902Reputation: 2902Reputation: 2902Reputation: 2902Reputation: 2902Reputation: 2902Reputation: 2902Reputation: 2902Reputation: 2902
What he's saying to you is:
Code:
#include <stdlib.h>
#include <stdio.h>

struct mystruct {
    int a;
    int b;
};

void this_is_ok( struct mystruct const input )
{
    printf("%d, %d\n", input.a, input.b);
    return;
}

void this_is_better( struct mystruct const *input )
{
    if ( input )
        printf("%d, %d\n", input->a, input->b);
    return;
}

int main(int argc, char *argv[])
{
    struct mystruct s = { 100, 200 };

    this_is_ok(s);
    this_is_better(&s);
    
    return EXIT_SUCCESS;
}
where better == more efficient: because this_is_better() doesn't have to take a copy of 's'.

Last edited by GazL; 08-19-2019 at 10:03 AM.
 
1 members found this post helpful.
Old 08-19-2019, 10:08 AM   #176
rtmistler
Moderator
 
Registered: Mar 2011
Location: MA, USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 8,054
Blog Entries: 13

Rep: Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501
Quote:
Originally Posted by jsbjsb001 View Post
So you're saying that I would setup a pointer to point to the structure, and pass the pointer (that's pointing to the structure) as an argument for the function, instead of passing the actual structure as an argument for the function?
Yes
 
1 members found this post helpful.
Old 08-20-2019, 06:19 AM   #177
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth? I would say I hope so but I'm not so sure about that... I could just be a figment of your imagination too.
Distribution: Currently OpenMandriva. Previously openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,085

Original Poster
Rep: Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595
Thanks guys, I think I get it now.

So now that structures are at least a little clearer to me now; I figured it was time to revisit GazL's example of of reallocating memory in post #149. While I've still gotta read up on some of the functions Gazl has used in their example, it does make a little more sense to me now. But putting aside some of the functions used like strrchr(), strdup(), etc, and while I see in the CODE block below "lines" is a pointer (I think) pointing to the "count" member of the "Lines" structure inside the square brackets (?); Am I right is saying "lineArray" is an "array of pointers"? Also, am I right in saying that "lines" is a pointer?

Code:
lines->lineArray[lines->count++] = s;
I can't say I completely understand the example though.

Thanks again for the help.
 
Old 08-20-2019, 07:51 AM   #178
rtmistler
Moderator
 
Registered: Mar 2011
Location: MA, USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 8,054
Blog Entries: 13

Rep: Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501Reputation: 3501
Quote:
Originally Posted by jsbjsb001 View Post
So now that structures are at least a little clearer to me now; I figured it was time to revisit GazL's example of of reallocating memory
As stated before, I do not recommend you play with dynamic allocation, and especially re-allocation. Just my opinion that you're asking for difficulties.
Quote:
Originally Posted by jsbjsb001 View Post
I see in the CODE block below "lines" is a pointer (I think) pointing to the "count" member of the "Lines" structure inside the square brackets (?); Am I right is saying "lineArray" is an "array of pointers"? Also, am I right in saying that "lines" is a pointer?
Code:
lines->lineArray[lines->count++] = s;
"lines" is a pointer, it is passed as such (bottom line below) as a function passing argument.

Yes, lineArray is declared as a pointer to character pointers, therefore it can be said that it represents an array of pointers.
Code:
struct Lines
{
    size_t count;
    size_t capacity;
    char **lineArray;
};

// later declaration as part of a function
char *addLine( struct Lines *lines, char *line )
 
2 members found this post helpful.
Old 08-20-2019, 08:18 AM   #179
jsbjsb001
Senior Member
 
Registered: Mar 2009
Location: Earth? I would say I hope so but I'm not so sure about that... I could just be a figment of your imagination too.
Distribution: Currently OpenMandriva. Previously openSUSE, PCLinuxOS, CentOS, among others over the years.
Posts: 3,085

Original Poster
Rep: Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595Reputation: 1595
Thank you RT.

Quote:
Originally Posted by rtmistler View Post
As stated before, I do not recommend you play with dynamic allocation, and especially re-allocation. Just my opinion that you're asking for difficulties.
...
Where do you suggest I go from here?
 
Old 08-20-2019, 08:29 AM   #180
GazL
LQ Guru
 
Registered: May 2008
Posts: 5,187
Blog Entries: 18

Rep: Reputation: 2902Reputation: 2902Reputation: 2902Reputation: 2902Reputation: 2902Reputation: 2902Reputation: 2902Reputation: 2902Reputation: 2902Reputation: 2902Reputation: 2902
If you ignore the pointer 'lines' for a moment, all that line of code is doing is simply:
Code:
linesArray[count] = s;
count++;
The lines-> prefix just tells it to use the count and linesArray members that are in the structure 'lines' points to.

'linesArray' is just a list of pointers, and works exactly like argv that you see in main(), except it point to the lines of input it reads in with getline(). Similarly, 'count' is the equivalent of argc, but keeps count of the number of lines.


To fully understand what's going on here, you will need to learn about the functions used and how they work.

P.S. I think rtmistler is right, dynamic memory managementis probably a bit beyond you at this point. Keep playing with pointers and structures, and pointers to structures until you get it down solid. then, you might want to try some simple linked lists using structures allocated with malloc() or strings with strdup() to get you started with dynamic memory. If I remember rightly, I think there's a chapter on linked lists in the book. There's also a chapter on malloc().

Last edited by GazL; 08-20-2019 at 08:38 AM.
 
2 members found this post helpful.
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] virtualbox installs pcbsd again and again and again straffetoebak Linux - Virtualization and Cloud 4 11-21-2014 07:14 PM
LXer: Do you want a serious—I mean serious—developer laptop? Then Dell and Ubuntu have the system fo LXer Syndicated Linux News 0 11-29-2012 03:30 PM
Firefox...I have tried and tried... Basslord1124 Fedora 4 10-29-2004 11:51 PM
my ps/2's wheel doesn't work. tried and tried but failed. Choey Linux - Hardware 5 09-17-2003 06:47 PM
I have tried and tried, I really have! Ewen Linux - General 13 01-14-2003 11:31 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:50 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration