2009-05-26 6 views
9

मुझे इंटरनेट के माध्यम से पैकेट स्थानांतरित करने की आवश्यकता है जिसका लंबाई गतिशील होना चाहिए।सी: गतिशील रूप से आकार वाले structs के लिए अनुशंसित शैली

struct packet 
{ 
    int id; 
    int filename_len; 
    char filename[]; 
}; 

समस्या यह है कि शून्य-लंबाई वाले सरणी आईएसओ-अनुरूप नहीं हैं।

क्या मुझे इसके बजाय char filename[1]; का उपयोग करना चाहिए? लेकिन फिर sizeof(struct packet) अब सही मूल्य वापस नहीं करेगा।

उत्तर

6

क्लासिक मुद्दा। आप बस इसके साथ सौदा कर सकते हैं (और ध्यान दें कि कंपाइलर संरचना आकार को गोलाकार करता है, जो कि (मुझे विश्वास है) की अनुमति देता है, या आप इस तरह कुछ कर सकते हैं:

struct packetheader { 
    int id; 
    int filename_len; 
}; 
struct packet { 
    struct packetheader h; 
    char filename[1]; 
}; 

यह परेशान है (आपको एच.आईडी, आदि का उपयोग करना है), लेकिन यह काम करता है। आम तौर पर मैं सिर्फ एक होने के साथ सौदा करता हूं, लेकिन उपरोक्त मामूली रूप से अधिक पोर्टेबल हो सकता है।

6

मुझे लगता है कि आपको मार्गदर्शन के लिए गतिशील रूप से आकार की संरचनाओं के कुछ मौजूदा उदाहरणों को देखना चाहिए। Win32 में टोकन एपीआई के बारे में मुझे पता है कि सबसे अच्छा उदाहरण है। वे का उपयोग मैक्रो ANYSIZE_ARRAY जो सिर्फ करने के लिए 1. रेमंड चेन नीचे का समाधान करता है एक व्यापक ब्लॉग लेख का ब्यौरा वास्तव में क्यों वे इस तरह से

ऐसे में नाकाम रहने के sizeof के रूप में संचालन के लिए के रूप में किया जाता है था। इससे कोई फर्क नहीं पड़ता कि आप गतिशील रूप से आकार की संरचना के लिए कौन सा समाधान चुनते हैं। sizeof एक संकलन समय ऑपरेशन है और आप रनटाइम पर संरचना का पुन: आकार बदल रहे होंगे। यह बस काम नहीं कर सकता है।

+0

आकार के साथ मेरा मतलब केवल संरचना का आकार था, गतिशील क्षेत्र नहीं, क्योंकि यूडीपी पैकेट प्राप्त करते समय मैंने पहली बार उस संरचना में पढ़ा जिसमें गतिशील क्षेत्र का आकार होता है, और फिर मैं गतिशील क्षेत्र पढ़ता हूं। – codymanix

4

मैं char filename[1] का उपयोग करने का सुझाव देता हूं और 0-बाइट को समाप्त करना शामिल करता हूं। इस तरह, आप इस तरह सही संरचना आकार malloc() कर सकते हैं और से बचने के एक बंद त्रुटियों:

ptr = malloc(sizeof(struct packet)+filename_len); 
strncpy(&ptr->filename, filename, filename_len); 

लेकिन रिसीवर पता चला है कि यह filename_len+1 बाइट्स पढ़ने के लिए की जरूरत है चाहिए।

3

वास्तव में zero-length arrays मानक का हिस्सा नहीं हैं। लेकिन आपके कोड स्निपेट में आपके पास एक लचीली सरणी है जो आईएसओ सी 99 मानक का हिस्सा है। यदि आपके लिए सी 99 का उपयोग करना संभव है, तो मैं एक लचीली सरणी का उपयोग करूंगा, अगर जेसप का सुझाव शायद सबसे अच्छा नहीं है।

संबंधित मुद्दे