繁体   English   中英

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

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

好的,我希望我能正确解释这一点。 我有一个结构:

typedef struct _MyData
{
   char Data[256];
   int  Index;
} MyData;

现在,我遇到了一个问题。 大多数情况下,MyData.Data可以使用256,但是在某些情况下,我需要将它可以容纳的字符数扩展为不同的大小。 我不能使用指针。 有什么方法可以在运行时调整数据大小吗? 怎么样? 代码受到赞赏。

谢谢

编辑:

尽管我非常感谢所有评论,但“也许尝试一下...”或“这样做”,或“您到底是错的...”的评论无济于事。 代码是这里的帮助。 如果您知道答案,请张贴代码。

和:

1-不能使用指针。 请不要试图弄清楚为什么,我只是不能2-结构被注入到另一个程序的内存中。 这就是为什么。 没有指针。

很抱歉在这里有点粗糙,但我在这里提出了问题,因为我已经尝试了所有可能认为可行的方法。 同样,我正在寻找代码。 在这一点上,我对“可能的工作...”或“您是否考虑过此...”不感兴趣。

再次感谢您和我的歉意

编辑2

为什么要这样回答?

您可以使用灵活的数组成员

typedef struct _MyData
{
   int  Index;
   char Data[];
} MyData;

这样您便可以分配适当的空间

MyData *d = malloc(sizeof *d + sizeof(char[100]));
d->Data[0..99] = ...;

稍后,您可以释放并分配另一块内存,并使指向MyData的指针指向该内存,这时在灵活数组成员( realloc )中将有更多/更少的元素。 请注意,您也必须将长度保存在某个地方。

在C99之前的时代,没有灵活的数组成员: char Data[]仅被视为类型不完整的数组,编译器会为此抱怨。 在这里,我向您推荐两种可能的方式

  • 使用指针: char *Data并使其指向分配的内存。 这将不会像使用嵌入式数组那样方便,因为您可能需要进行两种分配:一种分配给结构,另一种分配给指针所指向的内存。 如果程序中的情况允许,也可以在堆栈上分配结构。
  • 而是使用char Data[1] ,但将其视为较大的char Data[1] ,以使其覆盖整个分配的对象。 这是形式上未定义的行为,但是是一种通用技术,因此与编译器一起使用可能是安全的。

这里的问题是您的声明“我不能使用指针”。 您将必须这样做,这将使一切变得更加容易。 嘿,重新分配甚至复制您现有的数据,您还想要什么?

那么,为什么认为您不能使用指针呢? 最好尝试解决该问题。

您将像这样重新安排结构

typedef struct _MyData
{
   int  Index;
   char Data[256];
} MyData;

并使用malloc / realloc这样分配实例:

my_data = (MyData*) malloc ( sizeof(MyData) + extra_space_needed );

这是一个丑陋的方法,我不建议这样做(我将使用指针),但这是对您的问题的解答,该方法如何在没有指针的情况下进行。

局限性在于,每个结构仅允许一个可变大小的成员,并且必须位于最后。

让我总结一下在该线程中看到的两个重要点:

  1. 该结构用于通过某些IPC机制在两个程序之间进行交互
  2. 目标程序无法更改

因此,您不能以任何方式更改该结构,因为目标程序在尝试读取当前定义的程序时被卡住。 恐怕你被困住了。

您可以尝试找到获得同等行为的方法,或者找到一些恶作剧以迫使目标程序读取新结构(例如,修改可执行文件中的二进制偏移量)。 这些都是针对特定应用程序的,因此我无法提供更好的指导。

您可能考虑编写第三个程序以充当两者之间的接口。 它可以接收“长”消息并对其进行处理,然后将“短”消息继续传递到旧程序。 您可以很容易地将其注入IPC机制之间。

您可能可以这样做,而无需为数组分配指针:

typedef struct _MyData
{
    int Index;
    char Data[1];
} MyData;

以后,您可以这样分配:

int bcount = 256;
MyData *foo;

foo = (MyData *)malloc(sizeof(*foo) + bcount);

重新分配:

int newbcount = 512;
MyData *resized_foo;

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

从您所说的内容看来,您肯定必须将MyData保留为静态数据块。 在这种情况下,我认为向您开放的唯一选择是以某种方式(可选)将这些数据结构链接在一起,从而可以在其他过程中重新组合。

您需要和MyData其他成员,例如。

typedef struct _MyData
{
   int  Sequence;
   char Data[256];
   int  Index;
} MyData;

其中,“ Sequence标识了要在其中重组数据的降序序列(序列号为零将表示最终的数据缓冲区)。

问题在于您提出问题的方式。 不要考虑C语义:相反,请像黑客一样思考。 正是说明你目前如何让你的数据到另一个进程在正确的时间, 也是其他程序如何知道哪里有数据开始和结束。 其他程序是否期望以空值结尾的字符串? 如果用char [300]声明结构,其他程序会崩溃吗?

您会看到,当您说“将数据传递给另一个程序”时,您可能正在[a]欺骗另一个进程复制其前面的内容,[b]欺骗另一个程序让您覆盖其通常的“私有”记忆,或[c]其他方法。 无论是哪种情况,如果另一个程序都可以获取较大的数据,则一种方法可以将其获取。

我发现KIV的技巧非常有用。 虽然,我建议先调查指针问题。

如果您看一下malloc实现
请查看此IBM文章,清单5: 主分配器的伪代码 ),
分配时,内存管理器分配一个控制头,然后
然后根据您要求的大小释放可用空间。
这非常像说

typedef struct _MyData
{
   int  size;
   char Data[1]; // we are going to break the array-bound up-to size length
} MyData;

现在,你的问题是
您如何将这种(大小不正确的)结构传递给其他过程?

这给我们带来了一个问题,
另一个过程如何计算此数据的大小?
我希望将length字段作为通信的一部分。

如果您拥有所有这些,将指针传递给另一个进程怎么了?
其他进程是否会识别指向结构的指针与指向已分配内存的指针之间的区别?

您无法手动重新设置。

当我在简单数据保存系统上工作时,您可以做一些技巧。 (非常简单的文件系统)。

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

您没有说明“索引”值的用途。

据我了解,您正在使用所示结构将数据传递到另一个程序。 是否有原因不能将数据分解为256字节的块,然后相应地设置索引值? 例如

数据为512字节,因此您发送的一个结构的前256个字节和index = 0,然后发送另一个结构,其后的256个字节在数组中并且Index = 1。

一个非常非常简单的解决方案怎么样? 你能做:

typedef struct _MyData
{
   char Data[1024];
   int  Index;
} MyData;

我有一种感觉,我知道您的回答将是“否,因为我无法控制的其他程序期望有256个字节” ...如果这确实是您对我的回答,那么我的回答就变成:这是不可能的。

暂无
暂无

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

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