LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
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 02-11-2014, 03:19 AM   #1
errigour
Member
 
Registered: May 2009
Posts: 366

Rep: Reputation: 6
Struct pointer *ptr = *ptr ?


What does the line swap = *obj do exactly and also the line *obj = *refobj.

Code:
struct obj_data *refobj
struct obj_data *obj, swap;

swap = *obj;
*obj = *refobj;
 
Old 02-11-2014, 06:58 AM   #2
mina86
Member
 
Registered: Aug 2008
Distribution: Debian
Posts: 517

Rep: Reputation: 229Reputation: 229Reputation: 229
Recursively copy fields of struct obj_data from *obj to swap. In some sense, it's similar to memcpy(&swap, obj, sizeof swap);
 
Old 02-11-2014, 07:51 AM   #3
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,679
Blog Entries: 4

Rep: Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947
There would, of course, have to be a third line in that example, to finish the thought:

*refobj = swap;

These are simple assignment-statements; nothing "recursive" about it. (C is not that clever.) A block of memory (referenced by a pointer) is copied to a temporary location (which is local), then it is assigned from a location referenced by a second pointer. Then, presumably, the second location will next be assigned from the temporary. Thus swapping the content of the two locations.
 
1 members found this post helpful.
Old 02-11-2014, 08:06 AM   #4
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,883
Blog Entries: 13

Rep: Reputation: 4931Reputation: 4931Reputation: 4931Reputation: 4931Reputation: 4931Reputation: 4931Reputation: 4931Reputation: 4931Reputation: 4931Reputation: 4931Reputation: 4931
Interesting expansion of that. Where is it taking the memory to perform that? I.e. if one wishes to not use as much stack, they could code it as: (Providing obj and refobj were properly initialized that is)
Code:
struct obj_data *refobj, *obj, *swap;

obj = <passing argument 1>
refobj = <passing argument 2>
*swap = *obj;
*obj = *refobj;
*refobj = *swap
That all valid? And if so, where does it take memory to do this from? The heap? What happens if an obj_data is so large that you'll run out of memory?
 
Old 02-11-2014, 08:26 AM   #5
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,875
Blog Entries: 1

Rep: Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871
Segfaults. Fix:

Code:
struct obj_data *refobj, *obj, swap;

obj = <passing argument 1>
refobj = <passing argument 2>
swap = *obj;
*obj = *refobj;
*refobj = swap

Last edited by NevemTeve; 02-11-2014 at 08:27 AM.
 
1 members found this post helpful.
Old 02-11-2014, 08:31 AM   #6
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,883
Blog Entries: 13

Rep: Reputation: 4931Reputation: 4931Reputation: 4931Reputation: 4931Reputation: 4931Reputation: 4931Reputation: 4931Reputation: 4931Reputation: 4931Reputation: 4931Reputation: 4931
Yeah, you're right I should've tried the code before suggesting it. My question really was where the memory comes from, but now it appears the answer is that you have to have at least one place to put it; in this case on the stack. If one desires a non-stack option, then they would have to either scope swap higher than the function or allocate *swap from within the function.
 
Old 02-11-2014, 10:08 AM   #7
mina86
Member
 
Registered: Aug 2008
Distribution: Debian
Posts: 517

Rep: Reputation: 229Reputation: 229Reputation: 229
Quote:
Originally Posted by sundialsvcs View Post
These are simple assignment-statements; nothing "recursive" about it.
By recursive I meant that assigning one structure to another is equivalent, apart from potential differences in padding bytes, to assigning each member of the structure to corresponding member of the other structure. If such a member is structure itself, this rule is applied recursively.

Compilers end up doing equivalent of memcpy, even though I think they would be allowed not to copy padding bytes.
 
Old 02-11-2014, 10:12 PM   #8
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,679
Blog Entries: 4

Rep: Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947Reputation: 3947
... and the reason why I sought to very-politely correct you on that point is ... "C" is just not that smart. To "C," a structure is a contiguous block of memory; nothing more or less. It's exactly like a simple scalar variable, only bigger. (Recall that "C" doesn't even have a proper notion of a "string," only pchar.)

So, in C, if you assign something to something-else, a contiguous range of bytes gets copied verbatim from here to there; nothing more or less. Hence, no opportunity for "recursion," which implies deep-knowledge of what the contents of the structure actually represent. Which is exactly what other languages, including C++, can do. In "C," it's just an overglorified memcpy().

In the case at bar, the temporary, being a local variable, lives on the stack. The other blocks of storage are accessed by means of pointers which also live on the stack.
 
1 members found this post helpful.
Old 02-11-2014, 10:55 PM   #9
errigour
Member
 
Registered: May 2009
Posts: 366

Original Poster
Rep: Reputation: 6
Ok thanks.
 
Old 02-12-2014, 06:27 AM   #10
mina86
Member
 
Registered: Aug 2008
Distribution: Debian
Posts: 517

Rep: Reputation: 229Reputation: 229Reputation: 229
Quote:
Originally Posted by sundialsvcs View Post
So, in C, if you assign something to something-else, a contiguous range of bytes gets copied verbatim from here to there; nothing more or less. Hence, no opportunity for "recursion," which implies deep-knowledge of what the contents of the structure actually represent. Which is exactly what other languages, including C++, can do. In "C," it's just an overglorified memcpy().
This is clearly not true:
Code:
long long a;
unsigned char b;
b = a;
a = b;
Here's a relevant portion of the C99 standard:
Quote:
Originally Posted by ISO/IEEC 9899:TC3
§6.5.16.1¶2 In simple assignment (=), the value of the right operand is converted to the type of the assignment expression and replaces the value stored in the object designated by the left operand.
Performing a conversion implies understanding of the type.
 
Old 02-13-2014, 03:29 AM   #11
psionl0
Member
 
Registered: Jan 2011
Distribution: slackware_64 14.1
Posts: 722
Blog Entries: 2

Rep: Reputation: 124Reputation: 124
Quote:
Originally Posted by NevemTeve View Post
Segfaults. Fix:

Code:
struct obj_data *refobj, *obj, swap;

obj = <passing argument 1>
refobj = <passing argument 2>
swap = *obj;
*obj = *refobj;
*refobj = swap
Quote:
Originally Posted by rtmistler View Post
Yeah, you're right I should've tried the code before suggesting it. My question really was where the memory comes from, but now it appears the answer is that you have to have at least one place to put it; in this case on the stack. If one desires a non-stack option, then they would have to either scope swap higher than the function or allocate *swap from within the function.
The memory came from the calling function. <passing argument 1> and <passing argument 2> are pointers to the memory used by the calling function which this function refers to to do the swapping. So the memory could have been on the stack, heap or static data depending on how the calling function chose to allocate the memory.

(Note that swap was allocated on the stack by this function).

Last edited by psionl0; 02-13-2014 at 03:36 AM.
 
Old 02-13-2014, 03:39 AM   #12
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,875
Blog Entries: 1

Rep: Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871Reputation: 1871
Note: when a function wants to use (possibly large amount) of local data, it might do it this way:

Code:
void foo (size_t amount)
{
    char local [256], *allocated= NULL, *used= local;

    if (amount > sizeof (local)) {
        allocated= malloc (amount);
        if (!allocated) exit (111);
        used= allocated;
    }
    ...
RETURN:
    used= NULL;
    if (allocated) {
        free (allocated);
        allocated= NULL;
    }
}
 
  


Reply



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] container_of:why not "const typeof(*ptr) *__mptr=(ptr);" songcaidao Linux - Kernel 6 10-26-2013 08:35 AM
PTR question L1nuxn00b703 Linux - Newbie 1 06-26-2012 02:57 AM
[SOLVED] Pointer arithmetic question : *ptr++ or (*ptr)++ theKbStockpiler Programming 8 06-02-2010 11:12 AM
PTR record OTIM Linux - Server 3 11-22-2007 12:16 PM
PTR problem csdhiman Linux - Server 2 11-18-2007 01:20 PM

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

All times are GMT -5. The time now is 04:36 AM.

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
Open Source Consulting | Domain Registration