3

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

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

现在,我遇到了一个问题。大多数时候 MyData.Data 可以使用 256,但在某些情况下,我需要将它可以容纳的字符数量扩展到不同的大小。我不能使用指针。有没有办法在运行时调整数据大小?如何?代码表示赞赏。

谢谢

编辑:

虽然我非常感谢所有评论,但“也许试试这个……”或“那样做”,或“你是错的……”评论并没有帮助。代码是这里的帮助。如果您知道答案,请发布代码。

和:

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

抱歉在这里有点粗鲁,但我在这里问了这个问题,因为我已经尝试了所有认为可能有效的不同方法。同样,我正在寻找代码。在这一点上,我对“可能工作......”或“你考虑过这个......”不感兴趣

谢谢你,我再次道歉

编辑 2

为什么设置为已回答?

4

11 回答 11

18

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

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

这样您就可以分配适量的空间

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

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

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

  • 使用指针:char *Data并使其指向分配的内存。这不像使用嵌入式数组那样方便,因为您可能需要进行两次分配:一个用于结构,另一个用于指针指向的内存。如果程序中的情况允许,您也可以在堆栈上分配结构。
  • 使用 achar Data[1]代替,但将其视为更大,以便覆盖整个分配的对象。这是形式上未定义的行为,但它是一种常用技术,因此与您的编译器一起使用可能是安全的。
于 2009-07-20T13:42:09.763 回答
13

这里的问题是您的陈述“我不能使用指针”。您将不得不这样做,这将使一切变得更加容易。嘿,realloc 甚至会复制你现有的数据,你还想要什么?

那么为什么你认为你不能使用指针呢?最好尝试解决这个问题。

于 2009-07-20T13:33:34.903 回答
5

你会像这样重新安排结构

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

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

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

这是一种丑陋的方法,我不会推荐它(我会使用指针),但可以回答您的问题如何在没有指针的情况下进行操作。

一个限制是它只允许每个结构有一个可变大小的成员,并且必须在最后。

于 2009-07-20T13:37:20.467 回答
5

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

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

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

您可以尝试找到获得等效行为的方法,或者找到一些邪恶的技巧来强制目标程序读取新结构(例如,修改可执行文件中的二进制偏移量)。这都是非常具体的应用程序,所以我不能提供比这更好的指导。

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

于 2009-07-29T22:34:15.707 回答
2

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

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);
于 2009-07-20T13:38:10.500 回答
2

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

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

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

WhereSequence标识了重新组装数据的降序(零序号表示最终的数据缓冲区)。

于 2009-07-28T22:24:34.563 回答
2

问题在于你提出问题的方式。不要考虑 C 语义:相反,要像黑客一样思考。准确解释您当前如何在正确的时间将数据输入其他进程,以及其他程序如何知道数据的开始和结束位置。其他程序是否需要一个以空字符结尾的字符串?如果你用 char[300] 声明你的结构,其他程序会崩溃吗?

你看,当你说“传递数据”给另一个程序时,你可能是在 [a] 欺骗另一个进程复制你放在它前面的内容,[b] 欺骗另一个程序让你覆盖它通常的“私有” ' 记忆,或 [c] 其他一些方法。不管是哪种情况,如果其他程序可以获取您的更大数据,则有一种方法可以将其提供给他们。

于 2009-07-29T22:17:02.283 回答
0

我觉得KIV's 的把戏很有用。不过,我建议先调查指针问题。

如果您查看 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字段作为交流的一部分。

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

于 2009-07-20T13:46:37.980 回答
0

你不能手动重新调整。

当我在处理简单的数据保存系统时,你可以做一些我正在使用的技巧。(非常简单的文件系统)。

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;
}
于 2009-07-23T20:41:43.173 回答
0

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

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

数据为 512 字节,因此您发送一个结构,其中前 256 字节和索引 = 0,然后在数组中发送下一个 256 字节和索引 = 1 的结构。

于 2009-07-30T07:41:52.100 回答
0

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

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

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

于 2009-07-30T18:31:16.337 回答