473,624 Members | 2,005 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Allocating memory for part of a C struct

Here is the declaration of a struct from WinIoCtl.h:

//
// Structures for FSCTL_TXFS_READ _BACKUP_INFORMA TION
//

typedef struct _TXFS_READ_BACK UP_INFORMATION_ OUT {
union {

//
// Used to return the required buffer size if return code is
STATUS_BUFFER_O VERFLOW
//

DWORD BufferLength;

//
// On success the data is copied here.
//

BYTE Buffer[1];
} DUMMYUNIONNAME;
} TXFS_READ_BACKU P_INFORMATION_O UT, *PTXFS_READ_BAC KUP_INFORMATION _OUT;

Now Buffer can be various lengths and I know of only one way to allocate
memory for it (by allocating memory for the whole struct). I have seen
other similar structs that are not a union and have multiple arrays with a
similar declaration. Is there any way to allocate memory for such arrays?

Regards
Chris Saunders

Sep 1 '08 #1
10 1757
Chris Saunders wrote:
Here is the declaration of a struct from WinIoCtl.h:

//
// Structures for FSCTL_TXFS_READ _BACKUP_INFORMA TION
//

typedef struct _TXFS_READ_BACK UP_INFORMATION_ OUT {
union {

//
// Used to return the required buffer size if return code is
STATUS_BUFFER_O VERFLOW
//

DWORD BufferLength;

//
// On success the data is copied here.
//

BYTE Buffer[1];
} DUMMYUNIONNAME;
} TXFS_READ_BACKU P_INFORMATION_O UT, *PTXFS_READ_BAC KUP_INFORMATION _OUT;

Now Buffer can be various lengths and I know of only one way to allocate
memory for it (by allocating memory for the whole struct). I have seen
other similar structs that are not a union and have multiple arrays with a
similar declaration. Is there any way to allocate memory for such arrays?
Allocating memory is easy - you just use Marshal.AllocHG lobal or
stackalloc (though you have to do the size calculation yourself,
accounting for extra bytes, and mind the layout, particularly the
padding at the end).

The problem is working with such a thing. .NET P/Invoke marshaller
doesn't understand VLA structs, so the best you can get is the same
trick as in C++ - declare a "fixed" single-element array at the end,
and then, after you allocate enough memory for the struct, treat it as
N-element array. C# doesn't do any bound checks for fixed arrays, so
you can do it just fine.
Sep 1 '08 #2
My thanks to Pavel Minaev.

Regards
Chris Saunders
Sep 2 '08 #3
Pavel Minaev wrote:
Chris Saunders wrote:
>Here is the declaration of a struct from WinIoCtl.h:

//
// Structures for FSCTL_TXFS_READ _BACKUP_INFORMA TION
//

typedef struct _TXFS_READ_BACK UP_INFORMATION_ OUT {
union {

//
// Used to return the required buffer size if return code is
STATUS_BUFFER_ OVERFLOW
//

DWORD BufferLength;

//
// On success the data is copied here.
//

BYTE Buffer[1];
} DUMMYUNIONNAME;
} TXFS_READ_BACKU P_INFORMATION_O UT,
*PTXFS_READ_BA CKUP_INFORMATIO N_OUT;

Now Buffer can be various lengths and I know of only one way to
allocate memory for it (by allocating memory for the whole struct).
I have seen other similar structs that are not a union and have
multiple arrays with a similar declaration. Is there any way to
allocate memory for such arrays?

Allocating memory is easy - you just use Marshal.AllocHG lobal or
stackalloc (though you have to do the size calculation yourself,
accounting for extra bytes, and mind the layout, particularly the
padding at the end).

The problem is working with such a thing. .NET P/Invoke marshaller
doesn't understand VLA structs, so the best you can get is the same
trick as in C++ - declare a "fixed" single-element array at the end,
and then, after you allocate enough memory for the struct, treat it as
N-element array. C# doesn't do any bound checks for fixed arrays, so
you can do it just fine.
Why the C# and p/invoke information in this group, and why use
Marshal.AllocHG lobal?

C++ interop is so much easier.
Sep 3 '08 #4
"Ben Voigt [C++ MVP]" <rb*@nospam.nos pamwrote in message
news:ub******** ******@TK2MSFTN GP02.phx.gbl...
Why the C# and p/invoke information in this group, and why use
Marshal.AllocHG lobal?
I apologize - the groups come right after another, and the question is
rather atypical for a C/C++ developer (they usually just use malloc/new), so
I got confused there.
C++ interop is so much easier.
In fact, re-reading the original post, I see now that it doesn't even
reference any kind of interop at all - not even C++/CLI. So it was probably
a generic C++ question, which means that it boils down to the usual
non-standard-but-who-cares trick:

TXFS_READ_BACKU P_INFORMATION_O UT* trbio =
(TXFS_READ_BACK UP_INFORMATION_ OUT*)malloc(siz eof(TXFS_READ_B ACKUP_INFORMATI ON_OUT)
+ extra_bytes);

Sep 4 '08 #5
Pavel Minaev wrote:
"Ben Voigt [C++ MVP]" <rb*@nospam.nos pamwrote in message
news:ub******** ******@TK2MSFTN GP02.phx.gbl...
>Why the C# and p/invoke information in this group, and why use
Marshal.AllocH Global?

I apologize - the groups come right after another, and the question is
rather atypical for a C/C++ developer (they usually just use
malloc/new), so I got confused there.
>C++ interop is so much easier.

In fact, re-reading the original post, I see now that it doesn't even
reference any kind of interop at all - not even C++/CLI. So it was
True, but this is the C++/CLI group. So including some information on
interop might be useful (e.g. you can't use a buffer on the managed heap
unless you also pin it).
probably a generic C++ question, which means that it boils down to the
usual
non-standard-but-who-cares trick:

TXFS_READ_BACKU P_INFORMATION_O UT* trbio =

(TXFS_READ_BACK UP_INFORMATION_ OUT*)malloc(siz eof(TXFS_READ_B ACKUP_INFORMATI ON_OUT)
+ extra_bytes);
I don't see anything nonstandard about that. It's exactly what I would do,
except that in C++ I would use a cast keyword instead of the C-style cast.
Sep 5 '08 #6
"Ben Voigt [C++ MVP]" <rb*@nospam.nos pamwrote in message
news:e%******** ********@TK2MSF TNGP04.phx.gbl. ..
True, but this is the C++/CLI group. So including some information on
interop might be useful (e.g. you can't use a buffer on the managed heap
unless you also pin it).
Well, there's always stackalloc... er, _malloca
>probably a generic C++ question, which means that it boils down to the
usual
non-standard-but-who-cares trick:

TXFS_READ_BACK UP_INFORMATION_ OUT* trbio =

(TXFS_READ_BAC KUP_INFORMATION _OUT*)malloc(si zeof(TXFS_READ_ BACKUP_INFORMAT ION_OUT)
+ extra_bytes);

I don't see anything nonstandard about that. It's exactly what I would
do, except that in C++ I would use a cast keyword instead of the C-style
cast.
It is non-standard in a sense that the ISO C++ standard prescribes undefined
behavior for this construct. It is precisely why it was treated specially in
C99 in form of open-sized arrays, to guarantee that this idiom was actually
blessed by the Standard.
Sep 6 '08 #7
Pavel Minaev wrote:
"Ben Voigt [C++ MVP]" <rb*@nospam.nos pamwrote in message
news:e%******** ********@TK2MSF TNGP04.phx.gbl. ..
>True, but this is the C++/CLI group. So including some information
on interop might be useful (e.g. you can't use a buffer on the
managed heap unless you also pin it).

Well, there's always stackalloc... er, _malloca
That wouldn't put a buffer on the managed heap.
>
>>probably a generic C++ question, which means that it boils down to
the usual
non-standard-but-who-cares trick:

TXFS_READ_BAC KUP_INFORMATION _OUT* trbio =

(TXFS_READ_BA CKUP_INFORMATIO N_OUT*)malloc(s izeof(TXFS_READ _BACKUP_INFORMA TION_OUT)
+ extra_bytes);

I don't see anything nonstandard about that. It's exactly what I
would do, except that in C++ I would use a cast keyword instead of
the C-style cast.

It is non-standard in a sense that the ISO C++ standard prescribes
undefined behavior for this construct. It is precisely why it was
treated specially in C99 in form of open-sized arrays, to guarantee
that this idiom was actually blessed by the Standard.
Well, I'm pretty sure you are allowed to use the memory returned by malloc
as the TXFS_READ_BACKU P_INFORMATION_O UT structure, as long as the size is at
least sizeof TXFS_READ_BACKU P_INFORMATION_O UT. I suppose the issue is that
the compiler is not required to layout the structure with the array at the
end, so you might be walking over a footer or some other field when you
reference using the array name? Explicitly referencing the memory
immediately past the structure should be ok by the standard as long as the
requirement that the extra space be allocated by the caller is stated,
right?
Sep 8 '08 #8
On Sep 8, 5:30*pm, "Ben Voigt [C++ MVP]" <r...@nospam.no spamwrote:
"Ben Voigt [C++ MVP]" <r...@nospam.no spamwrote in message
news:e%******** ********@TK2MSF TNGP04.phx.gbl. ..
True, but this is the C++/CLI group. *So including some information
on interop might be useful (e.g. you can't use a buffer on the
managed heap unless you also pin it).
Well, there's always stackalloc... er, _malloca

That wouldn't put a buffer on the managed heap.
Why would it need to be on the managed heap, if it's just used for
interop?
It is non-standard in a sense that the ISO C++ standard prescribes
undefined behavior for this construct. It is precisely why it was
treated specially in C99 in form of open-sized arrays, to guarantee
that this idiom was actually blessed by the Standard.

Well, I'm pretty sure you are allowed to use the memory returned by malloc
as the TXFS_READ_BACKU P_INFORMATION_O UT structure, as long as the size isat
least sizeof TXFS_READ_BACKU P_INFORMATION_O UT. *I suppose the issue is that
the compiler is not required to layout the structure with the array at the
end, so you might be walking over a footer or some other field when you
reference using the array name? *Explicitly referencing the memory
immediately past the structure should be ok by the standard as long as the
requirement that the extra space be allocated by the caller is stated,
right?
Unfortunately, no. The Standard explicitly states that accessing an
array using an out-of-bounds index is U.B., without giving any
exceptions (such as the fact that memory accessed is allocated, etc).
In fact, you don't even have to dereference to get U.B. - it's already
happening at the pointer arithmetic stage. Recall that (p + i), where
p is pointer, and i is index, is only valid pointer arithmetics when
you're within the same object (object here defined as either array or
an individual value that the pointer is pointing to - not the
allocated memory block to which it belongs).
Sep 18 '08 #9
Pavel Minaev wrote:
On Sep 8, 5:30 pm, "Ben Voigt [C++ MVP]" <r...@nospam.no spamwrote:
>>"Ben Voigt [C++ MVP]" <r...@nospam.no spamwrote in message
news:e%****** **********@TK2M SFTNGP04.phx.gb l...
True, but this is the C++/CLI group. So including some information
on interop might be useful (e.g. you can't use a buffer on the
managed heap unless you also pin it).
>>Well, there's always stackalloc... er, _malloca

That wouldn't put a buffer on the managed heap.

Why would it need to be on the managed heap, if it's just used for
interop?
You presented it as a counter-example to my statement that you can't use a
buffer on the managed heap without pinning. Or that's how I understood it.
>
>>It is non-standard in a sense that the ISO C++ standard prescribes
undefined behavior for this construct. It is precisely why it was
treated specially in C99 in form of open-sized arrays, to guarantee
that this idiom was actually blessed by the Standard.

Well, I'm pretty sure you are allowed to use the memory returned by
malloc as the TXFS_READ_BACKU P_INFORMATION_O UT structure, as long as
the size is at least sizeof TXFS_READ_BACKU P_INFORMATION_O UT. I
suppose the issue is that the compiler is not required to layout the
structure with the array at the end, so you might be walking over a
footer or some other field when you reference using the array name?
Explicitly referencing the memory immediately past the structure
should be ok by the standard as long as the requirement that the
extra space be allocated by the caller is stated, right?

Unfortunately, no. The Standard explicitly states that accessing an
array using an out-of-bounds index is U.B., without giving any
exceptions (such as the fact that memory accessed is allocated, etc).
In fact, you don't even have to dereference to get U.B. - it's already
happening at the pointer arithmetic stage. Recall that (p + i), where
p is pointer, and i is index, is only valid pointer arithmetics when
you're within the same object (object here defined as either array or
an individual value that the pointer is pointing to - not the
allocated memory block to which it belongs).
I disagree. You can cast back to the original allocated object type, which
is array-of-char, and then all indices within the originally requested size
are legal and well-defined, including those past the sub-range of memory
which has been used as an object of class type.
Oct 9 '08 #10

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

Similar topics

4
745
by: Sameer | last post by:
Hello Group, This is one problem in programming that is troubling me. there is a segmentation fault just before creating memory to a structure ..i.e, just after the "allocating memory " statement. This happens for some inputs and not all. What can be the reason for such fault ?
15
6716
by: fix | last post by:
Hi all, I am writing a program using some structs, it is not running and I believe it is because there's some memory leak - the debugger tells me that the code causes the problem is in the malloc function. Is there any general rules that tell me when to allocate memory? I thought I don't have to if it is a variable that's not a pointer, and I have to if it is. I am a bit confused about the arrays particularly. In normal situations,...
5
3665
by: Johnathan Doe | last post by:
Why is is necessary to write a function that allocates memory for, or changes, a pointer to a char array using char** instead of char*? E.g. void modify_string( char** string ) { if( string == NULL ) return;
7
2093
by: boss_bhat | last post by:
Hi all , I am beginner to C programming. I have a defined astructure like the following, and i am using aliases for the different data types in the structure, typedef struct _NAME_INFO { struct _NAME_INFO *Next; ULONG LastId; ULONG Id; PVOID Value;
94
4699
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?
6
1741
by: toktam | last post by:
Hi guys! I defined a type like this: typedef struct { char *key; int freq; float pr; } TableEntry; and then I have an array of pointers to this struct:
3
447
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
12
2152
by: filia&sofia | last post by:
For example I would like to dynamically allocate memory for linked list (or complex struct etc.) that has not maximum number of elements. All that I can remember is that I have to have allocated variable to point to the linked list in main program and that I have to have some kind of a method that initializes the list (plus other methods to manipulate list, of course). "Correctly" means that there should be pointers involved, and possibly...
6
5170
by: Francois Grieu | last post by:
Hello, I'm asking myself all kind of questions on allocating an array of struct with proper alignment. Is the following code oorrect ? I'm most interested by the statement t = malloc(n*sizeof(r)) and (to a degree) by the surrounding error checking.
0
8236
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
8679
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
8621
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
8335
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
7159
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
6110
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
4079
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
2606
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
2
1482
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.