OK, I hope I explain this one correctly. I have a struct:
好的,我希望我能正确地解释这个。我有一个结构:
typedef struct _MyData
{
char Data[256];
int Index;
} MyData;
Now, I run into a problem. Most of the time MyData.Data is OK with 256, but in some cases I need to expand the amount of chars it can hold to different sizes. I can't use a pointer. Is there any way to resize Data at run time? How? Code is appreciated.
现在,我遇到了一个问题。大部分时间是MyData。数据可以使用256,但是在某些情况下,我需要扩展可以容纳不同大小的字符的数量。我不能用指针。是否有办法在运行时调整数据的大小?如何?代码是感激。
Thanks
谢谢
EDIT:
编辑:
While I am very thankful for all the comments, the "maybe try this..." or "do that", or "what you are dong is wrong..." comments are not helping. code is the help here. PLease if you know the answer post the code.
虽然我非常感谢所有的评论,但是“也许尝试一下……”或者“做那个”,或者“你是董先生错了……”的评论没有帮助。代码就是这里的帮助。如果你知道答案,请把代码写出来。
and:
和:
1- cannot use pointers. please don't try to figure out why, i just can't 2- the struct is being injected into another program's memory. that's why. no pointers.
1 -不能使用指针。请不要试图弄明白为什么,我只是不能2-结构被注入到另一个程序的内存中。这就是为什么。没有指针。
sorry for being a bit rough here but i asked the question here because I already tried all the different approaches that thought might work. Again, i am looking for code. At this point I am not interested in "might work..." or " have you considered this..."
不好意思,这里有点粗糙,但是我问了这个问题因为我已经尝试了所有可能的方法。同样,我在寻找代码。在这一点上,我对“可能工作……”或“你是否考虑过这个……”
thank you and my apologies again
再次感谢你和我的道歉。
EDIT 2
编辑2
Why was this set as answered?
这一套为什么要回答呢?
11 个解决方案
#1
18
You can use a flexible array member
您可以使用一个灵活的数组成员。
typedef struct _MyData
{
int Index;
char Data[];
} MyData;
So that you can then allocate the right amount of space
这样你就可以分配适当的空间。
MyData *d = malloc(sizeof *d + sizeof(char[100]));
d->Data[0..99] = ...;
Later, you can free, and allocate another chunk of memory and make a pointer to MyData
point to it, at which time you will have more / less elements in the flexible array member (realloc
). Note that you will have to save the length somewhere, too.
稍后,您可以*地分配另一个内存块,并将一个指针指向MyData指向它,在这个时候,您将在灵活的数组成员中拥有更多/更少的元素(realloc)。注意,您还必须在某个地方保存长度。
In Pre-C99 times, there isn't a flexible array member: char Data[]
is simply regarded as an array with incomplete type, and the compiler would moan about that. Here i recommend you two possible ways out there
在前c99时代,没有一个灵活的数组成员:char数据[]被简单地看作是一个不完全类型的数组,编译器会对此进行抱怨。这里我向你们推荐两种可能的方法。
- Using a pointer:
char *Data
and make it point to the allocated memory. This won't be as convenient as using the embedded array, because you will possibly need to have two allocations: One for the struct, and one for the memory pointed to by the pointer. You can also have the struct allocated on the stack instead, if the situation in your program allows this. - 使用一个指针:char *数据并使它指向已分配的内存。这不会像使用嵌入式数组那样方便,因为您可能需要有两个配置:一个用于结构,一个用于指针指向的内存。如果程序中的情况允许这样做,您还可以在堆栈上分配struct。
- Using a
char Data[1]
instead, but treat it as if it were bigger, so that it overlays the whole allocated object. This is formally undefined behavior, but is a common technique, so it's probably safe to use with your compiler. - 使用char数据[1],但是将其视为更大的数据,这样它就会覆盖整个分配的对象。这是一个正式的未定义的行为,但是是一种常见的技术,所以使用编译器是安全的。
#2
13
The problem here is your statement "I can't use a pointer". You will have to, and it will make everything much easier. Hey, realloc even copies your existing data, what do you want more?
这里的问题是“我不能使用指针”。你必须这样做,这会让一切变得更容易。嘿,realloc甚至复制了你现有的数据,你还想要什么?
So why do you think you can't use a pointer? Better try to fix that.
那么为什么你认为你不能使用指针呢?最好设法解决这个问题。
#3
5
You would re-arrange the structure like that
你会重新排列这样的结构。
typedef struct _MyData
{
int Index;
char Data[256];
} MyData;
And allocate instances with malloc/realloc like that:
用malloc/realloc来分配实例:
my_data = (MyData*) malloc ( sizeof(MyData) + extra_space_needed );
This is an ugly approach and I would not recommend it (I would use pointers), but is an answer to your question how to do it without a pointer.
这是一种很糟糕的方法,我不推荐它(我将使用指针),但它是对您的问题的一个回答,如何在没有指针的情况下完成它。
A limitation is that it allows for only one variable size member per struct, and has to be at the end.
一个限制是,它只允许每个结构中有一个可变大小的成员,并且必须在最后。
#4
4
Let me sum up two important points I see in this thread:
让我总结一下我在这篇文章中看到的两个要点:
- The structure is used to interact between two programs through some IPC mechanism
- 该结构用于通过IPC机制在两个程序之间进行交互。
- The destination program cannot be changed
- 目标程序无法更改。
You cannot therefore change that structure in any way, because the destination program is stuck trying to read it as currently defined. I'm afraid you are stuck.
因此,您不能以任何方式更改该结构,因为目标程序在试图按照当前定义的方式读取它。恐怕你被卡住了。
You can try to find ways to get the equivalent behavior, or find some evil hack to force the destination program to read a new structure (e.g., modifying the binary offsets in the executable). That's all pretty application specific so I can't give much better guidance than that.
您可以尝试找到方法来获得等效的行为,或者找到一些邪恶的hack来强制目标程序读取一个新的结构(例如,修改可执行文件中的二进制偏移量)。这些都是非常具体的应用,所以我不能给出更好的指导。
You might consider writing a third program to act as an interface between the two. It can take the "long" messages and do something with them, and pass the "short" messages onward to the old program. You can inject that in between the IPC mechanisms fairly easily.
您可以考虑编写第三个程序作为两者之间的接口。它可以接收“长”消息并对其进行处理,并将“短”消息传递给旧程序。你可以很容易地在IPC机制之间注入它。
#5
2
You may be able to do this like this, without allocating a pointer for the array:
您可以这样做,无需为数组分配一个指针:
typedef struct _MyData
{
int Index;
char Data[1];
} MyData;
Later, you allocate like this:
稍后,你会这样分配:
int bcount = 256;
MyData *foo;
foo = (MyData *)malloc(sizeof(*foo) + bcount);
realloc:
realloc:
int newbcount = 512;
MyData *resized_foo;
resized_foo = realloc((void *)foo, sizeof(*foo) + newbcount);
#6
2
It looks like from what you're saying that you definitely have to keep MyData
as a static block of data. In which case I think the only option open to you is to somehow (optionally) chain these data structures together in a way that can be re-assembled be the other process.
从你的意思看来,你必须将MyData作为静态数据块保存。在这种情况下,我认为唯一的选择就是以某种方式(可选地)将这些数据结构以一种可以重新组装的方式连接起来。
You'd need and additional member in MyData
, eg.
你需要和额外的成员在MyData,如。
typedef struct _MyData
{
int Sequence;
char Data[256];
int Index;
} MyData;
Where Sequence
identifies the descending sequence in which to re-assemble the data (a sequence number of zero would indicate the final data buffer).
其中序列标识了重新组合数据的降序序列(序号为0表示最终数据缓冲区)。
#7
1
The problem is in the way you're putting the question. Don't think about C semantics: instead, think like a hacker. Explain exactly how you are currently getting your data into the other process at the right time, and also how the other program knows where the data begins and ends. Is the other program expecting a null-terminated string? If you declare your struct with a char[300] does the other program crash?
问题在于你提出问题的方式。不要考虑C语义:相反,要像黑客一样思考。准确地解释您当前如何在正确的时间将您的数据导入到另一个进程中,以及其他程序如何知道数据从何处开始和结束。另一个程序是否期待一个以null结尾的字符串?如果您用char[300]声明您的结构,那么其他程序会崩溃吗?
You see, when you say "passing data" to the other program, you might be [a] tricking the other process into copying what you put in front of it, [b] tricking the other program into letting you overwrite its normally 'private' memory, or [c] some other approach. No matter which is the case, if the other program can take your larger data, there is a way to get it to them.
你看,当你说“传递数据”到另一个程序时,你可能是在欺骗另一个程序,把你放在它前面的东西复制过来,[b]欺骗其他程序,让你重写它通常的“私有”内存,或者[c]其他一些方法。无论哪种情况,如果另一个程序可以接收你的大数据,就有办法把它给他们。
#8
0
I find KIV
's trick quite usable. Though, I would suggest investigating the pointer issue first.
我发现KIV的把戏很有用。不过,我建议先调查一下指针问题。
If you look at the malloc implementations
(check this IBM article, Listing 5: Pseudo-code for the main allocator),
When you allocate, the memory manager allocates a control header and
then free space following it based on your requested size.
This is very much like saying,
如果您查看malloc实现(查看IBM的这篇文章,清单5:主分配器的伪代码),当您分配时,内存管理器会分配一个控制头,然后根据您所请求的大小来分配它。这很像说,
typedef struct _MyData
{
int size;
char Data[1]; // we are going to break the array-bound up-to size length
} MyData;
Now, your problem is,
How do you pass such a (mis-sized?) structure to this other process?
现在,您的问题是,如何将这样一个(错误大小的)结构传递给另一个进程?
That brings us the the question,
How does the other process figure out the size of this data?
I would expect a length
field as part of the communication.
这就引出了一个问题,另一个过程是如何计算出这些数据的大小的?我期望一个长度字段作为通信的一部分。
If you have all that, whats wrong with passing a pointer to the other process?
Will the other process identify the difference between a pointer to a structure and that to a allocated memory?
如果你有这一切,那么传递一个指针到另一个进程有什么错呢?另一个进程会识别指向结构的指针和分配给内存的指针之间的区别吗?
#9
0
You cant reacolate manualy.
你不能reacolate manualy。
You can do some tricks wich i was uning when i was working aon simple data holding sistem. (very simple filesystem).
当我在处理简单的数据保持sistem的时候,你可以做一些魔术。(非常简单的文件系统)。
typedef struct
{
int index ;
char x[250];
} data_ztorage_250_char;
typedef struct
{
int index;
char x[1000];
} data_ztorage_1000_char;
int main(void)
{
char just_raw_data[sizeof(data_ztorage_1000_char)];
data_ztorage_1000_char* big_struct;
data_ztorage_250_char* small_struct;
big_struct = (data_ztorage_1000_char*)big_struct; //now you have bigg struct
// notice that upper line is same as writing
// big_struct = (data_ztorage_1000_char*)(&just_raw_data[0]);
small_struct = (data_ztorage_250_char*)just_raw_data;//now you have small struct
//both structs starts at same locations and they share same memory
//addresing data is
small_struct -> index = 250;
}
#10
0
You don't state what the Index value is for.
你不知道索引值是多少。
As I understand it you are passing data to another program using the structure shown. Is there a reason why you can't break your data to send into chunks of 256bytes and then set the index value accordingly? e.g.
据我所知,您正在使用所示的结构将数据传递给另一个程序。您是否有理由不能将您的数据分解成256bytes的块,然后相应地设置索引值?如。
Data is 512 bytes so you send one struct with the first 256 bytes and index=0, then another with the next 256 bytes in your array and Index=1.
数据是512个字节,所以您发送一个结构,第一个256字节和索引=0,然后另一个在您的数组和索引=1中使用下一个256字节。
#11
0
How about a really, really simple solution? Could you do:
一个非常简单的解决方案如何?你能做的:
typedef struct _MyData
{
char Data[1024];
int Index;
} MyData;
I have a feeling I know your response will be "No, because the other program I don't have control over expects 256 bytes"... And if that is indeed your answer to my answer, then my answer becomes: this is impossible.
我有一种感觉,我知道你的回答是“不,因为我没有控制的另一个程序需要256字节”……如果这确实是你对我答案的回答,那么我的回答就变成:这是不可能的。
#1
18
You can use a flexible array member
您可以使用一个灵活的数组成员。
typedef struct _MyData
{
int Index;
char Data[];
} MyData;
So that you can then allocate the right amount of space
这样你就可以分配适当的空间。
MyData *d = malloc(sizeof *d + sizeof(char[100]));
d->Data[0..99] = ...;
Later, you can free, and allocate another chunk of memory and make a pointer to MyData
point to it, at which time you will have more / less elements in the flexible array member (realloc
). Note that you will have to save the length somewhere, too.
稍后,您可以*地分配另一个内存块,并将一个指针指向MyData指向它,在这个时候,您将在灵活的数组成员中拥有更多/更少的元素(realloc)。注意,您还必须在某个地方保存长度。
In Pre-C99 times, there isn't a flexible array member: char Data[]
is simply regarded as an array with incomplete type, and the compiler would moan about that. Here i recommend you two possible ways out there
在前c99时代,没有一个灵活的数组成员:char数据[]被简单地看作是一个不完全类型的数组,编译器会对此进行抱怨。这里我向你们推荐两种可能的方法。
- Using a pointer:
char *Data
and make it point to the allocated memory. This won't be as convenient as using the embedded array, because you will possibly need to have two allocations: One for the struct, and one for the memory pointed to by the pointer. You can also have the struct allocated on the stack instead, if the situation in your program allows this. - 使用一个指针:char *数据并使它指向已分配的内存。这不会像使用嵌入式数组那样方便,因为您可能需要有两个配置:一个用于结构,一个用于指针指向的内存。如果程序中的情况允许这样做,您还可以在堆栈上分配struct。
- Using a
char Data[1]
instead, but treat it as if it were bigger, so that it overlays the whole allocated object. This is formally undefined behavior, but is a common technique, so it's probably safe to use with your compiler. - 使用char数据[1],但是将其视为更大的数据,这样它就会覆盖整个分配的对象。这是一个正式的未定义的行为,但是是一种常见的技术,所以使用编译器是安全的。
#2
13
The problem here is your statement "I can't use a pointer". You will have to, and it will make everything much easier. Hey, realloc even copies your existing data, what do you want more?
这里的问题是“我不能使用指针”。你必须这样做,这会让一切变得更容易。嘿,realloc甚至复制了你现有的数据,你还想要什么?
So why do you think you can't use a pointer? Better try to fix that.
那么为什么你认为你不能使用指针呢?最好设法解决这个问题。
#3
5
You would re-arrange the structure like that
你会重新排列这样的结构。
typedef struct _MyData
{
int Index;
char Data[256];
} MyData;
And allocate instances with malloc/realloc like that:
用malloc/realloc来分配实例:
my_data = (MyData*) malloc ( sizeof(MyData) + extra_space_needed );
This is an ugly approach and I would not recommend it (I would use pointers), but is an answer to your question how to do it without a pointer.
这是一种很糟糕的方法,我不推荐它(我将使用指针),但它是对您的问题的一个回答,如何在没有指针的情况下完成它。
A limitation is that it allows for only one variable size member per struct, and has to be at the end.
一个限制是,它只允许每个结构中有一个可变大小的成员,并且必须在最后。
#4
4
Let me sum up two important points I see in this thread:
让我总结一下我在这篇文章中看到的两个要点:
- The structure is used to interact between two programs through some IPC mechanism
- 该结构用于通过IPC机制在两个程序之间进行交互。
- The destination program cannot be changed
- 目标程序无法更改。
You cannot therefore change that structure in any way, because the destination program is stuck trying to read it as currently defined. I'm afraid you are stuck.
因此,您不能以任何方式更改该结构,因为目标程序在试图按照当前定义的方式读取它。恐怕你被卡住了。
You can try to find ways to get the equivalent behavior, or find some evil hack to force the destination program to read a new structure (e.g., modifying the binary offsets in the executable). That's all pretty application specific so I can't give much better guidance than that.
您可以尝试找到方法来获得等效的行为,或者找到一些邪恶的hack来强制目标程序读取一个新的结构(例如,修改可执行文件中的二进制偏移量)。这些都是非常具体的应用,所以我不能给出更好的指导。
You might consider writing a third program to act as an interface between the two. It can take the "long" messages and do something with them, and pass the "short" messages onward to the old program. You can inject that in between the IPC mechanisms fairly easily.
您可以考虑编写第三个程序作为两者之间的接口。它可以接收“长”消息并对其进行处理,并将“短”消息传递给旧程序。你可以很容易地在IPC机制之间注入它。
#5
2
You may be able to do this like this, without allocating a pointer for the array:
您可以这样做,无需为数组分配一个指针:
typedef struct _MyData
{
int Index;
char Data[1];
} MyData;
Later, you allocate like this:
稍后,你会这样分配:
int bcount = 256;
MyData *foo;
foo = (MyData *)malloc(sizeof(*foo) + bcount);
realloc:
realloc:
int newbcount = 512;
MyData *resized_foo;
resized_foo = realloc((void *)foo, sizeof(*foo) + newbcount);
#6
2
It looks like from what you're saying that you definitely have to keep MyData
as a static block of data. In which case I think the only option open to you is to somehow (optionally) chain these data structures together in a way that can be re-assembled be the other process.
从你的意思看来,你必须将MyData作为静态数据块保存。在这种情况下,我认为唯一的选择就是以某种方式(可选地)将这些数据结构以一种可以重新组装的方式连接起来。
You'd need and additional member in MyData
, eg.
你需要和额外的成员在MyData,如。
typedef struct _MyData
{
int Sequence;
char Data[256];
int Index;
} MyData;
Where Sequence
identifies the descending sequence in which to re-assemble the data (a sequence number of zero would indicate the final data buffer).
其中序列标识了重新组合数据的降序序列(序号为0表示最终数据缓冲区)。
#7
1
The problem is in the way you're putting the question. Don't think about C semantics: instead, think like a hacker. Explain exactly how you are currently getting your data into the other process at the right time, and also how the other program knows where the data begins and ends. Is the other program expecting a null-terminated string? If you declare your struct with a char[300] does the other program crash?
问题在于你提出问题的方式。不要考虑C语义:相反,要像黑客一样思考。准确地解释您当前如何在正确的时间将您的数据导入到另一个进程中,以及其他程序如何知道数据从何处开始和结束。另一个程序是否期待一个以null结尾的字符串?如果您用char[300]声明您的结构,那么其他程序会崩溃吗?
You see, when you say "passing data" to the other program, you might be [a] tricking the other process into copying what you put in front of it, [b] tricking the other program into letting you overwrite its normally 'private' memory, or [c] some other approach. No matter which is the case, if the other program can take your larger data, there is a way to get it to them.
你看,当你说“传递数据”到另一个程序时,你可能是在欺骗另一个程序,把你放在它前面的东西复制过来,[b]欺骗其他程序,让你重写它通常的“私有”内存,或者[c]其他一些方法。无论哪种情况,如果另一个程序可以接收你的大数据,就有办法把它给他们。
#8
0
I find KIV
's trick quite usable. Though, I would suggest investigating the pointer issue first.
我发现KIV的把戏很有用。不过,我建议先调查一下指针问题。
If you look at the malloc implementations
(check this IBM article, Listing 5: Pseudo-code for the main allocator),
When you allocate, the memory manager allocates a control header and
then free space following it based on your requested size.
This is very much like saying,
如果您查看malloc实现(查看IBM的这篇文章,清单5:主分配器的伪代码),当您分配时,内存管理器会分配一个控制头,然后根据您所请求的大小来分配它。这很像说,
typedef struct _MyData
{
int size;
char Data[1]; // we are going to break the array-bound up-to size length
} MyData;
Now, your problem is,
How do you pass such a (mis-sized?) structure to this other process?
现在,您的问题是,如何将这样一个(错误大小的)结构传递给另一个进程?
That brings us the the question,
How does the other process figure out the size of this data?
I would expect a length
field as part of the communication.
这就引出了一个问题,另一个过程是如何计算出这些数据的大小的?我期望一个长度字段作为通信的一部分。
If you have all that, whats wrong with passing a pointer to the other process?
Will the other process identify the difference between a pointer to a structure and that to a allocated memory?
如果你有这一切,那么传递一个指针到另一个进程有什么错呢?另一个进程会识别指向结构的指针和分配给内存的指针之间的区别吗?
#9
0
You cant reacolate manualy.
你不能reacolate manualy。
You can do some tricks wich i was uning when i was working aon simple data holding sistem. (very simple filesystem).
当我在处理简单的数据保持sistem的时候,你可以做一些魔术。(非常简单的文件系统)。
typedef struct
{
int index ;
char x[250];
} data_ztorage_250_char;
typedef struct
{
int index;
char x[1000];
} data_ztorage_1000_char;
int main(void)
{
char just_raw_data[sizeof(data_ztorage_1000_char)];
data_ztorage_1000_char* big_struct;
data_ztorage_250_char* small_struct;
big_struct = (data_ztorage_1000_char*)big_struct; //now you have bigg struct
// notice that upper line is same as writing
// big_struct = (data_ztorage_1000_char*)(&just_raw_data[0]);
small_struct = (data_ztorage_250_char*)just_raw_data;//now you have small struct
//both structs starts at same locations and they share same memory
//addresing data is
small_struct -> index = 250;
}
#10
0
You don't state what the Index value is for.
你不知道索引值是多少。
As I understand it you are passing data to another program using the structure shown. Is there a reason why you can't break your data to send into chunks of 256bytes and then set the index value accordingly? e.g.
据我所知,您正在使用所示的结构将数据传递给另一个程序。您是否有理由不能将您的数据分解成256bytes的块,然后相应地设置索引值?如。
Data is 512 bytes so you send one struct with the first 256 bytes and index=0, then another with the next 256 bytes in your array and Index=1.
数据是512个字节,所以您发送一个结构,第一个256字节和索引=0,然后另一个在您的数组和索引=1中使用下一个256字节。
#11
0
How about a really, really simple solution? Could you do:
一个非常简单的解决方案如何?你能做的:
typedef struct _MyData
{
char Data[1024];
int Index;
} MyData;
I have a feeling I know your response will be "No, because the other program I don't have control over expects 256 bytes"... And if that is indeed your answer to my answer, then my answer becomes: this is impossible.
我有一种感觉,我知道你的回答是“不,因为我没有控制的另一个程序需要256字节”……如果这确实是你对我答案的回答,那么我的回答就变成:这是不可能的。