2009-11-28 14 views
5

मैं ffcall (विशेष रूप से ffcall का avcall पैकेज) लाइब्रेरी का उपयोग कर गतिशील रूप से चरम कार्यों को पैरामीटर को पुश करने के लिए उपयोग कर रहा हूं। यानी हमारे पासशून्य पॉइंटर्स और एफएफकॉल लाइब्रेरी

int blah (char *a, int b, double c, ...); 

और हम इस फ़ंक्शन को उपयोगकर्ता से लिया गया मानों के साथ कॉल करना चाहते हैं। ऐसा करने के लिए, हम समारोह के avcall संस्करण बनाने: अब

int av_blah (char *a, int b, double c, char **values, int num_of_values) 
{ 
    av_alist alist; 
    int i, ret; 
    av_start_int (alist, &blah, &ret); //let it know which function 
    av_ptr (alist, char*, a); // push values onto stack starting from left 
    av_int (alist, b); 
    av_double (alist, c); 
    for (i=0;i<num_of_values;i++) 
    { 
     // do what you want with values and add to stack 
    } 
    av_call (alist); //call blah() 

    return (ret); 
} 

, समारोह के साथ मैं avcall का उपयोग कर रहा है:

int read_row (struct some_struct *a, struct another_struct *b[], ...); 

और यह इतनी की तरह इस्तेमाल किया जाता है:

struct some_struct a; 
struct another_struct **b = fill_with_stuff(); 

char name[64]; 
int num; 
while (read_row (&a, b, name, &num)==0) 
{ 
    printf ("name=%s, num=%d\n", name, num); 
} 

लेकिन मैं इस फ़ंक्शन से कुछ निश्चित मूल्यों को कैप्चर करने के लिए avcall का उपयोग करना चाहता हूं और मुझे पहले से ही यह जानकारी नहीं पता है। तो मैंने सोचा कि मैं सिर्फ प्रकार के अनुसार शून्य संकेत की एक सरणी और फिर malloc जगह बनाने चाहते हैं:

char printf_string[64]=""; //need to build printf string inside av_read_row() 
void **vals = Calloc (n+1, sizeof (void*)); //wrapper 
while (av_read_row (&a, b, vals, n, printf_string) == 0) 
{ 
    // vals should now hold the values i want 
    av_printf (printf_string, vals, n); //get nonsense output from this 
    // free the mallocs which each vals[i] is pointing to 
    void **ptrs = vals; 
    while (*ptrs) { 
     free (*ptrs); //seg faults on first free() ? 
     *ptrs=NULL; 
     ptrs++; 
    } 
    //reset printf_string 
    printf_string[0]='\0'; 
    printf ("\n"); 
} 

और av_read_row बस है:

int av_read_row (struct some_struct *a, struct another_struct *b[], void **vals, int num_of_args, char *printf_string) 
{ 
    int i, ret; 
    av_alist alist; 

    av_start_int (alist, &read_row, &ret); 
    av_ptr (alist, struct some_struct *, a); 
    av_ptr (alist, struct another_struct **, b); 

    for (i=0;i<num_of_args;i++) 
    { 
     switch (type) //for simplicity 
     { 
      case INT: { 
       vals[i] = Malloc (sizeof (int)); 
       av_ptr (alist, int*, vals[i]); 
       strcat (printf_string, "%d, "); 
       break; 
      } 
      case FLOAT: { 
       //Same thing 
      } 
      //etc 
     } 
    } 

    av_call (alist); 
    return (ret); 
} 

मैं स्मृति भ्रष्टाचार के एक समूह के अनुभव कर रहे हैं त्रुटियां और ऐसा लगता है कि यह पसंद नहीं है कि मैं यहां क्या कर रहा हूं। मैं जिस तरह से किया, उससे कुछ भी गलत नहीं हो सकता, क्या आप? फिलहाल, जब मैं लूप के दौरान av_read_row के अंदर mallocs को मुक्त करने का प्रयास करता हूं, तो यह पसंद नहीं करता है। क्या कोई देख सकता है कि मैं क्या कर रहा हूं, अगर कुछ भी हो?

धन्यवाद

+0

मुझे लगता है कि आपके स्ट्रैट में कुछ याद आ रहा है ... मैं av_ सामान से वास्तव में परिचित नहीं हूं, लेकिन अगर printf_string ओवरराइटिंग हो रहा है तो आपको कुछ बुरा परिणाम मिलेंगे। –

+1

क्या यह (http://www.haible.de/bruno/packages-ffcall.html) पैकेज है जिसका आप उपयोग कर रहे हैं? –

उत्तर

0

मैं कोड पर अधिक स्पष्ट विवरण में जाना नहीं था, लेकिन अगले

  1. तर्क की बड़ी संख्या पारित करने के लिए ढेर का उपयोग करते हुए कह सकते हैं के रूप में ढेर सीमित है, उचित नहीं है। मुझे यकीन नहीं है कि av_stuff वास्तव में स्टैक सीमा की जांच करता है।
  2. क्या वेरिएबल को स्टैक करने के बजाए एक ही ऑपरेशन करने के लिए एक आसान तरीका नहीं है?
1

एकमात्र जानकारी जिसे मैं आसानी से avcall पर पा सकता हूं, 2001 से है, लेकिन यह पॉज़िक्स का सुझाव देता है। यदि आप लिनक्स पर अपनी सामग्री चला सकते हैं, तो valgrind आपकी मेमोरी दोषों को एक जिफ्फ़ी में मिलेगा। यह एक शानदार उपकरण है।