snprintf分段错误

时间:2015-07-23 16:26:51

标签: c++ c segmentation-fault printf

我试图理解C中的char指针。 基本上我正在做的是声明一个char *指针main并在另一个函数中通过引用传递并在那里进行修改。现在,我想在main中打印char的值,这给了我分段错误。但是,如果我在被调用函数中打印该值,则打印正常。

另外,当我尝试在main中的char指针上执行snprintf时,我再次得到分段错误但不在被调用函数中。

我搜索并尝试理解字符和指针,但无法调试它。

下面是带注释的代码:

#include<stdio.h>



int main(void)
{
    char *a;
    int ret;
    /* Below line gives Segmentation Fault. */
//  snprintf(a,10,"%s","Hello");
    /* Below line prints '(null)'.OK */
    printf("Before Function Call: %s\n",a); 
    ret = func(&a);
    /* Below line prints count of characters returned from func .OK */
    printf("Characters written : %d\n",ret);
    /* Below line gives Segmentation Fault. */
    printf("After Function Call: %s\n",a);
    return 1;
}

int func(char *b)
{
    int ret = 0;
    /* Below line prints blank. Why? Above it prints '(null)'*/
    printf("    In func-> Before operation: %s\n",b);
    ret = snprintf(b,10,"%s",", World");
    /* Below line prints ' World'. OK */
    printf("    In func-> After operation: %s\n",b);
    return ret;
}

3 个答案:

答案 0 :(得分:4)

让我们逐行完成这些功能。

char *a;

这里你声明一个到目前为止指向无处的指针。

/* Below line gives Segmentation Fault. */
//  snprintf(a,10,"%s","Hello");

当然可以。当a指向“无处”或“任何地方”时,这是未定义的行为。您应该首先通过一种方式或其他方式分配内存,然后让a指向那里。然后你可以按照你的描述使用它。

ret = func(&a);

在这里,您将a地址传递给func() - 这没关系。

/* Below line gives Segmentation Fault. */
printf("After Function Call: %s\n",a);

a已更改,不再是上面的空指针,而是指向无法读取任何内容的目标。再次出现未定义的行为。

return 1;

这意味着失败。更好return 0因为这意味着成功。

int func(char *b)

停止。上面你将&a传递给了func。由于achar *&a将是char **。 B但func接受char *。因此存在导致错误的差异。

/* Below line prints blank. Why? Above it prints '(null)'*/
printf("    In func-> Before operation: %s\n",b);

因为上面打印了a,所以在这里打印b &a

ret = snprintf(b,10,"%s",", World");

在这里,您可以在b点,a指向main()点。 a是一个指针,在32位系统上的大小为4,在64位系统上的大小为8。不应该滥用存储字符串。

printf("    In func-> After operation: %s\n",b);

这是偶然的;你再次有未定义的行为,可能会扰乱调用者的堆栈帧。

让我们改进你的代码:

// prototype - make the function known to main() so that the right calling convention is used
int func(char *b);

int main(void)
{
    char *a = malloc(100); // should be adjusted depending on the needs...
    int ret;
    /* Below line no longer gives Segmentation Fault now. */
    snprintf(a,10,"%s","Hello");
    printf("Before Function Call: %s\n",a); 
    ret = func(a);
    /* Below line prints count of characters returned from func .OK */
    printf("Characters written : %d\n",ret);
    printf("After Function Call: %s\n",a);
    free(a); // as we alloc'ed it...
    return 0; // as we didn't notice anything going wrong...
}

int func(char *b)
{
    int ret;
    printf("    In func-> Before operation: %s\n",b);
    // Here is the qustion: do we want to append or to overwrite?
    char * b_append = b + strlen(b);
    ret = snprintf(b_append,10,"%s",", World");
    printf("    In func-> After operation: %s\n",b);
    printf("    In func-> We appended %s\n",b_append);
    return ret;
}

答案 1 :(得分:1)

尝试像这样定义a

char a[10];

目前您正在向snprintf传递未初始化的指针,因此当snprintf写入时会出现未定义的行为。

答案 2 :(得分:0)

int func(char *b)
             ^requires char pointer 

你传递的是

ret = func(&a);
            ^This is of type char **