簡體   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