2013-05-31 67 views
1

我想爲將來通過memcpy包含一個包含以前動態分配內存的指針的結構分配內存。獲取包含動態分配內存的結構的大小

也就是說,我有一個結構

struct test_struct { 
    int num; 
    char *values; 
}; 

test_struct.values包含num量長度LENGTH的字符串。我知道我無法獲得分配指針的內存大小,所以我只是通過num來跟蹤它。獲得這個結構體的大小的最簡單/最乾淨的方法是什麼?

唯一的解決辦法我能想出是一樣的東西

buf = malloc(sizeof(test_struct) + (num * LENGTH));

但我是新來這種低級別的內存管理的東西,所以有可能是更好的東西。

+0

該結構的大小是不變的 – tay10r

+0

的結構永遠不會改變的大小,它只是'的sizeof(test_struct)'。如果你想知道分配的內存總量,那麼是的,你需要'num * sizeof(* values)' –

+0

@泰勒正確。但是,包含它的緩衝區必須分配足夠的內存來保存'values' 。這就是爲什麼我用'num * LENGTH'計算'values'的大小,然後增加'struct'本身的大小。 – justynnuff

回答

4

如果你想memcpy兩個結構,那麼他們兩個的內存必須是連續的。但是您必須事先確定num

struct test_struct { 
    int num; 
    char ** values; 
} * TestStruct; 

int _num = 0; 

// find _num 

TestStruct = malloc (sizeof (struct test_struct) + (sizeof(char*) * _num) + (LENGTH * _num)); 

TestStruct->num = _num; 
TestStruct->values = &TestStruct + sizeof (struct test_struct); 

for (int i = 0; i < _num; i++){ 
    TestStruct->values[i] = &TestStruct + sizeof (struct test_struct) + (i * LENGTH); 
} 

我改變的char *爲char原因**是因爲使用的char *它變得更難第一(我假設他們是空值終止)後訪問字符串。另外,在調用memcpy之後,您必須更新新結構中的所有字符串指針。

memcpy的你可以這樣做:

memcpy (buf, TestStruct->values[0], LENGTH * TestStruct->num); 

但buf中,但是,你只能看到第一個字符串(除非你的字符串不是空終止)。您必須在每個空終止字符後增加指針,直到您知道num,您已達到緩衝區的末尾。


現在,我瞭解了更多關於您的請求的上下文,請考慮以下事項。

如果您使用的是UDP數據包,則應該將數據發送到一個數據包中,以便按照您期望的順序到達。當發送多個數據包時,它可能不按順序到達。 因此,您需要確保數據的大小爲< = 512字節 - 這是UDP數據包的最大大小。 另外,您需要確保所有數據都在連續內存中。我會假設你有你的數據已經在您在本示例中提供的結構:

// this function puts the struct in contiguous memory 

int PrepareBuffer (struct test_struct TestStruct, char ** buffer){ 

    char * cast = (char *) &TestStruct->num; 

    * buffer = malloc ((TestStruct->num * LENGTH) + sizeof (int)); 

    for (int i = 0; i < sizeof (int); i++) *buffer[i] = cast[i]; 

    for (int i = 0; i < (TestStruct->num * LENGTH); i++) *buffer[i + sizeof (int)] = TestStruct->values[i]; 
    return 0; 
} 

你必須落實緩衝區映射到struct test_struct接收端的另一個功能。另外,爲了清晰起見,我省略了錯誤檢查。你應該檢查數據包在分配內存之前有多大, (它必須是< = 512) 。您還應該檢查以確保malloc返回一個非空指針。

+0

你是怎麼得到12的? – Magn3s1um

+0

一個指針是一個64位機器上的8個字節,並且int大概是4.它只是一個猜測,並且可能或可能不準確 – tay10r

+0

哦,單詞,我的思想立即轉到32位 – Magn3s1um

0

您應該只需要分配4個字節(用於32位linux上的整數)和4個字節用於char *(32位,64是8)。

你真的在問什麼,我怎麼知道需要分配多少內存給char *值指向的區域。你在你正在做的事情中弄明白這一點。然後將值設置爲buf的位置。如果你有多個字符串,並且你不想只把它們全部在那個區域中混合在一起,並且必須弄清楚哪一個是你自己,那麼有一個評論給我打擊,這是正確的方法。

0

我假設你想爲結構和值指向的緩衝區分配內存。如果是這樣,這是正確的。要指向額外的空間,做buf->values = buf + 1;(這是假設你聲明的buf作爲struct test_struct buf;

+0

這個答案來自前一陣子,但僅僅爲了澄清'buf-> values = buf + 1'沒有指向額外的空間,它指向了一個偏移字節'buf-> num'在struct中,它會溢出到'buf-> values'中。我認爲你寫的意思是'buf-> values =&buf-> values + sizeof(char *);' – tay10r

+0

我不知道。在C中,向指向struct x的指針添加1會添加sizeof(struct x),而不是1.如果向char指針添加1,則確實會添加1.將1添加到32位整數指針,並且實際上將添加1 4! – DoxyLover

+0

啊,我在C++中遇到過,但我不知道它是從C開始的。 – tay10r