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

时间:2009-07-20 13:31:15

标签: c resize char

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

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

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

由于

编辑:

虽然我非常感谢所有的评论,但“也许试试这个......”或“做那个”,或“你是什么东西是错的......”评论没有帮助。代码是这里的帮助。如果你知道代码后面的答案,那么就这样做。

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

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

再次感谢你和我的道歉

编辑2

为什么设置为已解答?

11 个答案:

答案 0 :(得分: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并使其指向已分配的内存。这不如使用嵌入式数组那么方便,因为您可能需要有两个分配:一个用于struct,另一个用于指针指向的内存。如果程序中的情况允许,您也可以在堆栈上分配结构。
  • 改为使用char Data[1],但将其视为更大,以便覆盖整个分配的对象。这是一种形式上未定义的行为,但这是一种常见的技术,因此与编译器一起使用可能是安全的。

答案 1 :(得分:13)

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

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

答案 2 :(得分:5)

你会像那样重新安排结构

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

并使用malloc / realloc分配实例:

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

这是一种丑陋的方法,我不推荐它(我会使用指针),但是如果没有指针就可以解答你的问题。

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

答案 3 :(得分:5)

让我总结一下我在这个帖子中看到的两个要点:

  1. 该结构用于通过某种IPC机制在两个程序之间进行交互
  2. 目标程序无法更改
  3. 因此,您无法以任何方式更改该结构,因为目标程序试图按当前定义读取它。我怕你被困住了。

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

    您可以考虑编写第三个程序作为两者之间的接口。它可以接收“长”消息并对它们执行某些操作,并将“短”消息传递给旧程序。你可以很容易地在IPC机制之间注入它。

答案 4 :(得分:2)

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

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

稍后,你这样分配:

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

答案 5 :(得分:2)

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

您需要MyData中的其他成员,例如

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

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

答案 6 :(得分:2)

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

你看,当你说“将数据传递给另一个程序”时,你可能会欺骗另一个进程复制你放在它前面的东西,[b]欺骗其他程序让你覆盖它通常是“私人”记忆,或[c]其他一些方法。无论是哪种情况,如果其他程序可以获取更大的数据,那么 就可以获得它们。

答案 7 :(得分:0)

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

如果你看一下malloc实现
check this IBM article, Listing 5: Pseudo-code for the main allocator),
分配时,内存管理器分配一个控制头和
然后根据您要求的尺寸自由空间 这非常像是在说,

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

现在,你的问题是,
你如何将这种(错误的?)结构传递给另一个过程?

这给我们带来了问题,
另一个过程如何计算出这些数据的大小?
我希望length字段是沟通的一部分。

如果你有这一切,将指针传递给另一个进程有什么不对? 另一个进程是否会识别指向a的指针之间的区别 结构和分配的内存?

答案 8 :(得分: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;
}

答案 9 :(得分:0)

您没有说明索引值是什么。

据我了解,您使用所示结构将数据传递到另一个程序。 您有没有理由不能将数据分成256字节的块,然后相应地设置索引值? e.g。

数据是512字节,因此您发送一个结构,前256个字节,索引= 0,然后另一个结构,数组中接下来的256个字节,索引= 1。

答案 10 :(得分:0)

真正简单的解决方案怎么样?你能做到吗?

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

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