473,779 Members | 2,078 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Allocating single memory block for multiple structures

Hi,

I need to allocate, using malloc(), a single
memory block to hold two structures and a
variable length string. Is it safe (portable,
alignment-wise) to sum up the sizeof's of those
structures and add the length of the string,
as in this snippet?

const char *canonname = "domain.tld ";
struct addrinfo *ai;
struct sockaddr_in *sa;

ai = (struct addrinfo *) malloc(sizeof(s truct addrinfo) +
sizeof(struct sockaddr_in) +
strlen(canonnam e) + 1);

sa = (struct sockaddr_in *) (((char *) ai) + sizeof(struct addrinfo));
sa->sin_family = PF_INET;
sa->sin_port = htons(80);
sa->sin_addr.s_add r = INADDR_ANY;

ai->ai_addr = (struct sockaddr *) sa;
ai->ai_addrlen = sizeof(struct sockaddr_in);
ai->ai_canonname = ((char *) ai) +
sizeof(struct addrinfo) +
sizeof(struct sockaddr_in);
strcpy(ai->ai_canonname , canonname);

Thanks,
Everton
Nov 14 '05 #1
6 2350
Everton da Silva Marques wrote:
Hi,

I need to allocate, using malloc(), a single
memory block to hold two structures and a
variable length string. Is it safe (portable,
alignment-wise) to sum up the sizeof's of those
structures and add the length of the string,
as in this snippet?
No.
const char *canonname = "domain.tld ";
struct addrinfo *ai;
struct sockaddr_in *sa;

ai = (struct addrinfo *) malloc(sizeof(s truct addrinfo) +
sizeof(struct sockaddr_in) +
strlen(canonnam e) + 1);

sa = (struct sockaddr_in *) (((char *) ai) + sizeof(struct addrinfo));
Here's the problem: A `struct sockaddr_in' might require
stricter alignment than a `struct addrinfo', so just sliding
forward by `sizeof(struct addrinfo)' bytes may not arrive at
an address where it's legitimate for a `struct sockaddr_in'
to begin.
sa->sin_family = PF_INET;
sa->sin_port = htons(80);
sa->sin_addr.s_add r = INADDR_ANY;

ai->ai_addr = (struct sockaddr *) sa;
ai->ai_addrlen = sizeof(struct sockaddr_in);
ai->ai_canonname = ((char *) ai) +
sizeof(struct addrinfo) +
sizeof(struct sockaddr_in);
You're safe on this one, though, because an array of
`char' can begin at any location without concern for
alignment issues.
strcpy(ai->ai_canonname , canonname);


Although the code above is not portable and not safe,
there is a safe and portable and simple alternative:

struct addrstuff {
struct addrinfo ai;
struct sockaddr_in sa;
} *both;

both = malloc(sizeof *both + strlen(canonnam e) + 1);
if (both == NULL)
crash_and_burn( );

both->sa.sin_famil y = PF_INET;
/* etc. */
both->ai.ai_addr = (struct sockaddr *) &both->sa;
/* etc. */
both->ai.ai_canonnam e = (char *)(both + 1);
strcpy (both->ai.ai_canonnam e, canonname);

Since the compiler knows the alignment requirement of
every type, it knows whether to insert padding bytes in
the middle of a `struct addrstuff' so that both elements
will be properly aligned.

It may also add padding at the very end of a `struct
addrstuff' so that everything would remain properly aligned
if you decided to allocate an array of them, but from your
point of view this is wasted space. It'll probably be a
small amount of waste, but if you Really Really want to
uglify the code to save those few bytes, you could write

both = malloc(offsetof (struct addrstuff, sa)
+ sizeof(struct sockaddr_in)
+ strlen(canonnam e) + 1);
...
both->ai.ai_canonnam e = (char*)(&both->sa + 1);

Personally, I don't think this is worth while nowadays.

--
Er*********@sun .com

Nov 14 '05 #2
>I need to allocate, using malloc(), a single
memory block to hold two structures and a
variable length string. Is it safe (portable,
alignment-wise) to sum up the sizeof's of those
structures and add the length of the string,
as in this snippet?
No. Consider what happens if you put the string, or a fixed-length
prime-length character array, FIRST. Chances are a struct following
it is going to be misaligned if it requires alignment at all.

There is no guarantee that a struct sockaddr_in doesn't require
stricter alignment than a struct addrinfo.

const char *canonname = "domain.tld ";
struct addrinfo *ai;
struct sockaddr_in *sa;

ai = (struct addrinfo *) malloc(sizeof(s truct addrinfo) +
sizeof(struct sockaddr_in) +
strlen(canonnam e) + 1);

sa = (struct sockaddr_in *) (((char *) ai) + sizeof(struct addrinfo));
sa->sin_family = PF_INET;
sa->sin_port = htons(80);
sa->sin_addr.s_add r = INADDR_ANY;

ai->ai_addr = (struct sockaddr *) sa;
ai->ai_addrlen = sizeof(struct sockaddr_in);
ai->ai_canonname = ((char *) ai) +
sizeof(struct addrinfo) +
sizeof(struct sockaddr_in);
strcpy(ai->ai_canonname , canonname);


Gordon L. Burditt
Nov 14 '05 #3
Eric Sosman <Er*********@su n.com> wrote in message news:<40******* *******@sun.com >...

Although the code above is not portable and not safe,
there is a safe and portable and simple alternative:

struct addrstuff {
struct addrinfo ai;
struct sockaddr_in sa;
} *both;


In this example, is it safe to cast
(struct addrstuff *) to (struct addrinfo *),
so to access members in both->ai ?
Like this:

struct addrinfo *ai = (struct addrinfo *) both;
ai->ai_addr = ...

I mean:

1) is member ordering guaranteed in struct's ?
2) does the first member always align at
the begining of the struct?

BTW, awesome answer, thanks!

--
Everton
Nov 14 '05 #4
Everton da Silva Marques wrote:
Eric Sosman <Er*********@su n.com> wrote in message news:<40******* *******@sun.com >...
struct addrstuff {
struct addrinfo ai;
struct sockaddr_in sa;
} *both;
In this example, is it safe to cast (struct addrstuff *) to (struct
addrinfo *), so to access members in both->ai ?


Yes, but wholly unnecessary and a possible cause of trouble in the
future, as you might decide to change the order of the structure's
members later.
struct addrinfo *ai = (struct addrinfo *) both;
ai->ai_addr = ...
both->ai.ai_addr = ...
1) is member ordering guaranteed in struct's ?


Yes, basically.

--
++acr@,ka"
Nov 14 '05 #5
ev*******@yahoo .com.br (Everton da Silva Marques) wrote in message news:<cc******* *************** ***@posting.goo gle.com>...
Eric Sosman <Er*********@su n.com> wrote in message news:<40******* *******@sun.com >...

Although the code above is not portable and not safe,
there is a safe and portable and simple alternative:

struct addrstuff {
struct addrinfo ai;
struct sockaddr_in sa;
} *both;
In this example, is it safe to cast
(struct addrstuff *) to (struct addrinfo *),
so to access members in both->ai ?
Like this:

struct addrinfo *ai = (struct addrinfo *) both;
ai->ai_addr = ...


Yes.
I mean:

1) is member ordering guaranteed in struct's ?
Yes.
2) does the first member always align at
the begining of the struct?


Yes.
Nov 14 '05 #6
"Gordon Burditt" <go***********@ burditt.org> wrote in message
news:c9******** @library2.airne ws.net...
I need to allocate, using malloc(), a single
memory block to hold two structures and a
variable length string. Is it safe (portable,
alignment-wise) to sum up the sizeof's of those
structures and add the length of the string,
as in this snippet?


No. Consider what happens if you put the string, or a fixed-length
prime-length character array, FIRST. Chances are a struct following
it is going to be misaligned if it requires alignment at all.

There is no guarantee that a struct sockaddr_in doesn't require
stricter alignment than a struct addrinfo.

/snip/

You will need to calculate the alignment of
each struct, and then calculate the offset
of the next location that is compatible with
that alignment.

You can use a macro like this to calculate
the alignment of a type X:

#define alignof(X) (sizeof(struct{ X a;char b})-sizeof(struct{X a;}))

The parameter X is a type name (usually a typedef name
or a type name that is syntactically correct for the
macro expansion). The macro will expand to a constant
expression. Some compilers, like M$ visual C++ will
issue a warning about the unnamed struct, but just turn
off that stupid warning.

Nov 14 '05 #7

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

Similar topics

18
6681
by: Tron Thomas | last post by:
Given the following information about memory management in C++: ----- The c-runtime dynamic memory manager (and most other commercial memory managers) has issues with fragmentation similar to a hard drive file system. Over time, the more often use call new/delete or alloc/free, there will be gaps and fragments in the heap. This can lead to inefficient use of available memory, as well as cache-hit inefficiencies.
1
3037
by: Kane | last post by:
When you create node 1 you allocate memory and link it Again when you create node 2 you would allocate memory for that node in a different section of the code. Is there more efficient way where I can allocate memory once and use it to create new node in list. -Thanks -Kane
5
1908
by: mikegw | last post by:
Hello all. I am currently using an implementation of sysV shared memory. The entire shared memory is allocated is one continuous block of which I get the pointer to the head, everything should be done as offsets from this. At the moment I have two data structures, a head to a linked list which in it contains the pointer to the first element in the linked list( this is redundant as far as I can work out) and the list itself. The data...
94
4774
by: smnoff | last post by:
I have searched the internet for malloc and dynamic malloc; however, I still don't know or readily see what is general way to allocate memory to char * variable that I want to assign the substring that I found inside of a string. Any ideas?
4
3634
by: Tom | last post by:
I am seeking an efficient method to "clip" the front-end off a large block of memory. For example, let's say there is a block of memory holding 100,000 structures of "data" and you want to drop the first 20,000 structures and free that memory. Must the program overwrite the first 80,000 structures? for(int i = 0; i < 80000; ++i) data = data; Followed by a realloc() call. Thus effectively clipping off the
8
1932
by: Francine.Neary | last post by:
I'm experimenting with a program that manipulates a large matrix, i.e. a 2-deep array. I started by just allocating this in one go, but later it occurred to me that, as there are still some very old systems around where such a large allocation might fail, perhaps it would be better to split the allocation into many allocations, one for each row, to increase portability to legacy systems. The advantage I see is that the memory allocator...
3
6681
by: Amit_Basnak | last post by:
Dear Friends I have the follwoing function "tss_fe_get_own_info" which has the arguments as shows below tss_fe_get_own_info(char *user_id, tss_user_profile_t **p_buf_UserSecInfo, error_status_t *retStatus) // Structure tss_user_profile_t from the function typedef struct {
10
1768
by: Chris Saunders | last post by:
Here is the declaration of a struct from WinIoCtl.h: // // Structures for FSCTL_TXFS_READ_BACKUP_INFORMATION // typedef struct _TXFS_READ_BACKUP_INFORMATION_OUT { union { //
25
4739
by: Andreas Eibach | last post by:
Hi again, one of the other big woes I'm having... typedef struct perBlockStru /* (structure) Long words per block */ { unsigned long *lword; } lwperBlockStru_t;
0
9636
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
10306
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10139
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...
1
10075
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 Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9931
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
8961
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...
0
6727
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
5504
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4037
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

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.