2014-03-01 27 views
1

我一直在努力,现在调试这一个小时,但我失败了。我有一个可变参数函数,set_buffer,这需要在缓冲区设置输入字符串转换为分段故障与可变参数函数

void set_buffer(char *buf, int num_str, ...) { // destructively sets buffer with the strings provided, in the order they are provided. Must provide number of arguments so function knows where to stop. 
    size_t length = sizeof(buf)/sizeof(*buf); // strlen() fails because it depends on the null terminator... 
    printf("length: %d\n", length); 
    va_list args; 
    va_start(args, num_str); // va_start takes on the NAME of the last known parameter in the function to determine where to start taking in optional arguments 
    for (int i = 0, offset = 0; i < num_str && offset < length; ++i) { 
     char *str = va_arg(args, char *); 
     printf("length of str: %d\n", strlen(str)); // SEG FAULT ERROR 
     offset += snprintf(buf+offset, strlen(str)+1, "%s", str); // I must be adding too much of an offset, resulting in a seg fault 
     if (i != (num_str - 1)) { 
      //offset -= 1; 
     } 
    } 
    va_end(args); 
} 

我怀疑它可能有一些做的,从所使用的va_list ARGS参数不正确的抓取。

+0

究竟什么是你的问题,你为什么不提供再现问题的完整最低工作的代码示例? – 2014-03-01 00:34:43

回答

3

sizeof(buf)/sizeof(*buf)只能如果buf具有数组类型,而不是一个指针。取决于您是在32位还是64位目标上,它将评估为常数4或8。

你需要传递一个参数指定可用缓冲区大小。

这不正好指向崩溃,因为结果是仅用于offset < length测试。 (这是顺便说一下,不正确的。你应该使用length限制指定snprintf的空间)要看看会发生什么错误,我们需要一个完整的,独立的测试案例。

+0

因为我们不能使用sizeof(),所以我会如何获得函数外的缓冲区的大小? –

+1

@GeorgeNewton缓冲区大小是需要考虑的。在任何你通过缓冲区的地方,也要通过它的大小。如有必要,使用'struct'。或者硬编码一个保守的大小,所以它总是事先知道。 – Potatoswatter

+0

我不明白。所以你告诉我,然后当我做char * ptr = malloc(...) - 除非硬编码,否则我找不到长度/大小? –

3

你不能这样做sizeof(buf)/sizeof(*buf),因为

sizeof(buf) == sizeof(char*) 
sizeof(*buf) == sizeof(char) 

那么,你是切实做好:sizeof(char*)/sizeof(char)