使用stdarg重新分配

时间:2013-04-29 03:19:27

标签: c realloc

我正在尝试使用stdarg( library )标头连接字符串,但我做错了。 有一种更简单的方法可以使用realloc连接字符串吗?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
void concatenaCodigo(char *string, char *format, ...){
    va_list args;
    va_start(args, format);
    int n = vsnprintf(NULL, 0, format, args);
    string = (char*) realloc (string, n);
    if (string != NULL) {
        printf("Realloc OK!\n");
        vsprintf(string, format, args);
        va_end(args);
    }
    else {
        free (string);
        puts ("Error (re)allocating memory");
        exit (1);
    }

}
int main(){
    char *codigoC = NULL;
    concatenaCodigo(codigoC, "Test%s%s","asd","asd");
    printf("%s\n", codigoC);
}

我做了改动。代码应该如下所示?连接还没有工作。

char* concatenaCodigo(char *format, ...){
    va_list args;
    va_start(args, format);
    int n = vsnprintf(NULL, 0, format, args);
    char * newString;
    newString = (char*) malloc(n);
    vsprintf(newString, format, args);
    va_end(args);
    return newString;
}
int main(){
    char *codigoC = NULL;
    codigoC = concatenaCodigo("Test%s%s", "asd", "asd");
    printf("%s\n", codigoC);
}

3 个答案:

答案 0 :(得分:3)

修订后的代码中的问题是您没有正确重置va_list。你有:

char* concatenaCodigo(char *format, ...){
    va_list args;
    va_start(args, format);
    int n = vsnprintf(NULL, 0, format, args);
    char * newString;
    newString = (char*) malloc(n);
    vsprintf(newString, format, args);
    va_end(args);
    return newString;
}
int main(){
    char *codigoC = NULL;
    codigoC = concatenaCodigo("Test%s%s", "asd", "asd");
    printf("%s\n", codigoC);
}

你需要:

char *concatenaCodigo(char *format, ...)
{
    va_list args;
    va_start(args, format);
    int n = vsnprintf(NULL, 0, format, args) + 1;  /* Note the +1! */
    va_end(args);                                  /* vsnprintf() 'uses up' args */
    char *newString = (char *) malloc(n);
    if (newString != 0)
    {
        va_start(args, format);                        /* Restart args */
        vsprintf(newString, format, args);
        va_end(args);
    }
    return newString;
}

int main(void)
{
    char *codigoC = concatenaCodigo("Test%s%s", "asd", "asd");
    if (codigoC != 0)
        printf("%s\n", codigoC);
    free(codigoC);
    return 0;
}

请注意,<stdarg.h>是标题,而不是库。

答案 1 :(得分:0)

指针不是通过引用传递的,所以当你这样做时:

void concatenaCodigo(char *string, char *format, ...){
    // ...
    string = (char*) realloc (string, n);
}

您正在覆盖传入的指针,并且永远不会从函数中获取新值。

concatenaCodigo应返回新分配的字符串:

char* concatenaCodigo(char *format, ...) {
    // ...
    return string;
}

int main() {
    char *codigoC = concatenaCodigo("Test%s%s","asd","asd");
    printf("%s\n", codigoC);
}

此外,如果free(string)失败,您应该致电realloc。您不应将NULL指针传递给free()

答案 2 :(得分:0)

为避免丢失引用,我更改了函数以接收指向char数组的指针。

void concatenaCodigo(char **message, char *format, ...)
{
    va_list args;
    va_start(args, format);
    int n = vsnprintf(NULL, 0, format, args) + 1;  /* Note the +1! */
    va_end(args);                                  /* vsnprintf() 'uses up' args */
    char *newString = (char *) malloc(n);
    if (newString != 0)
    {
        va_start(args, format);                        /* Restart args */
        vsprintf(newString, format, args);
        va_end(args);
    }
    *message = newString;
}