简体   繁体   English

在运行时将char [x]调整为char [y]

[英]Resizing a char[x] to char[y] at runtime

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. 大多数情况下,MyData.Data可以使用256,但是在某些情况下,我需要将它可以容纳的字符数扩展为不同的大小。 I can't use a pointer. 我不能使用指针。 Is there any way to resize Data at run time? 有什么方法可以在运行时调整数据大小吗? How? 怎么样? Code is appreciated. 代码受到赞赏。

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. 1-不能使用指针。 please don't try to figure out why, i just can't 2- the struct is being injected into another program's memory. 请不要试图弄清楚为什么,我只是不能2-结构被注入到另一个程序的内存中。 that's why. 这就是为什么。 no pointers. 没有指针。

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? 为什么要这样回答?

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 ). 稍后,您可以释放并分配另一块内存,并使指向MyData的指针指向该内存,这时在灵活数组成员( realloc )中将有更多/更少的元素。 Note that you will have to save the length somewhere, too. 请注意,您也必须将长度保存在某个地方。

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. 在C99之前的时代,没有灵活的数组成员: char Data[]仅被视为类型不完整的数组,编译器会为此抱怨。 Here i recommend you two possible ways out there 在这里,我向您推荐两种可能的方式

  • Using a pointer: char *Data and make it point to the allocated memory. 使用指针: char *Data并使其指向分配的内存。 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. 如果程序中的情况允许,也可以在堆栈上分配结构。
  • Using a char Data[1] instead, but treat it as if it were bigger, so that it overlays the whole allocated object. 而是使用char Data[1] ,但将其视为较大的char Data[1] ,以使其覆盖整个分配的对象。 This is formally undefined behavior, but is a common technique, so it's probably safe to use with your compiler. 这是形式上未定义的行为,但是是一种通用技术,因此与编译器一起使用可能是安全的。

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? 嘿,重新分配甚至复制您现有的数据,您还想要什么?

So why do you think you can't use a pointer? 那么,为什么认为您不能使用指针呢? Better try to fix that. 最好尝试解决该问题。

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. 局限性在于,每个结构仅允许一个可变大小的成员,并且必须位于最后。

Let me sum up two important points I see in this thread: 让我总结一下在该线程中看到的两个重要点:

  1. The structure is used to interact between two programs through some IPC mechanism 该结构用于通过某些IPC机制在两个程序之间进行交互
  2. 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 (eg, modifying the binary offsets in the executable). 您可以尝试找到获得同等行为的方法,或者找到一些恶作剧以迫使目标程序读取新结构(例如,修改可执行文件中的二进制偏移量)。 That's all pretty application specific so I can't give much better guidance than that. 这些都是针对特定应用程序的,因此我无法提供更好的指导。

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机制之间。

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: 重新分配:

int newbcount = 512;
MyData *resized_foo;

resized_foo = realloc((void *)foo, sizeof(*foo) + newbcount);

It looks like from what you're saying that you definitely have to keep MyData as a static block of data. 从您所说的内容看来,您肯定必须将MyData保留为静态数据块。 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. 在这种情况下,我认为向您开放的唯一选择是以某种方式(可选)将这些数据结构链接在一起,从而可以在其他过程中重新组合。

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). 其中,“ Sequence标识了要在其中重组数据的降序序列(序列号为零将表示最终的数据缓冲区)。

The problem is in the way you're putting the question. 问题在于您提出问题的方式。 Don't think about C semantics: instead, think like a hacker. 不要考虑C语义:相反,请像黑客一样思考。 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? 如果用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. 您会看到,当您说“将数据传递给另一个程序”时,您可能正在[a]欺骗另一个进程复制其前面的内容,[b]欺骗另一个程序让您覆盖其通常的“私有”记忆,或[c]其他方法。 No matter which is the case, if the other program can take your larger data, there is a way to get it to them. 无论是哪种情况,如果另一个程序都可以获取较大的数据,则一种方法可以将其获取。

I find KIV 's trick quite usable. 我发现KIV的技巧非常有用。 Though, I would suggest investigating the pointer issue first. 虽然,我建议先调查指针问题。

If you look at the malloc implementations 如果您看一下malloc实现
( check this IBM article, Listing 5: Pseudo-code for the main allocator ), 请查看此IBM文章,清单5: 主分配器的伪代码 ),
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, 这非常像说

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. 我希望将length字段作为通信的一部分。

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? 其他进程是否会识别指向结构的指针与指向已分配内存的指针之间的区别?

You cant reacolate manualy. 您无法手动重新设置。

You can do some tricks wich i was uning when i was working aon simple data holding sistem. 当我在简单数据保存系统上工作时,您可以做一些技巧。 (very simple filesystem). (非常简单的文件系统)。

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;
}

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? 是否有原因不能将数据分解为256字节的块,然后相应地设置索引值? eg 例如

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个字节和index = 0,然后发送另一个结构,其后的256个字节在数组中并且Index = 1。

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个字节” ...如果这确实是您对我的回答,那么我的回答就变成:这是不可能的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM