C sprintf数组char指针

时间:2013-11-04 16:46:12

标签: c arrays pointers

有谁能告诉我这里我做错了什么?为什么我的程序会出现段错误? 我想在string1string2之间插入第三个字符串。

#include <stdio.h>

int main (void) 
{
char *string1 = "HELLO";
char *string2 = "WORLD";
char *stringX  = "++++";
char *string3;
printf ("%s,%s\n",string1,string2);
sprintf(string3,"%s%s%s",string1,stringX,string2);
printf ("NewVar: %s",string3);
}

为什么sprintf不将结果值存储在string3指向的内存地址?当我将string3声明为普通数组但不是指向char数组的指针时,它可以工作。

我认为string3并没有指向任何内存位置,但是当我做printf("%p",string3);

时似乎确实如此

输出:

# ./concat
HELLO,WORLD,0x40042

5 个答案:

答案 0 :(得分:26)

想象一下,你有一堆现金要放在公文包里。你需要什么?你必须衡量现金的大小,才能知道公文包的使用大小,而且你需要一个方便携带现金的手柄。

现金是你的字符串。公文包是内存空间。公文包句柄是指针。

  1. 衡量您的现金:strlen(string1) + strlen(string2) + strlen(stringX)。 称之为“总计”。
  2. 现在得到一个足够大的公文包:malloc(total+1)
  3. 并对其进行处理:string3
  4. 将所有这些拼凑在一起......

    char *string3 = malloc(strlen(string1)+strlen(stringX)+strlen(string2)+1);
    sprintf(string3, "%s%s%s", string1, stringX, string2);
    

    第一次尝试出了什么问题?你没有公文包。你有现金,你有一个手柄,但中间没有公文包。它似乎以一种随机的方式工作,因为编译器给你一个脏垃圾站来持有现金。有时垃圾箱有空间,有时它没有空间。如果没有,我们称之为“分段错误”。

    每当有数据时,都必须为该数据分配空间。编译器为常量字符串分配空间,如"HELLO"。但是你必须为在运行时构建的字符串分配空间。

答案 1 :(得分:9)

sprintf会将值存储在那里。问题是指针string3具有未初始化的值,因此您只是覆盖随机内存。

您有一个选择是使用静态字符串缓冲区:

char string3[20];
snprintf(string3, sizeof(string3), "Hello!");

或者,您可以在基于GNU libc的系统上使用asprintf自动分配适当的空间:

char * string3;
asprintf(&string3, "Hello!");
// ... after use
free(string3); // free the allocated memory

答案 2 :(得分:7)

sprintf不会为其写入的字符串分配内存。你必须提供一个有效的字符串供它写入,但目前正在传递一个未初始化的指针。

最简单的解决方法是更改​​

char *string3;
sprintf(string3,"%s%s%s",string1,stringX,string2);

char string3[200];
sprintf(string3,"%s%s%s",string1,stringX,string2);

在这种情况下,您可能希望使用snprintf代替

来防止缓冲区溢出
char string3[200];
snprintf(string3,sizeof(string3),"%s%s%s",string1,stringX,string2);

或者,您也可以通过在运行时确定string3的大小来处理更大长度的源字符串,并在完成后记住free这个内存。

char* string3 = malloc(strlen(string1) + strlen(stringX) + strlen(string2) + 1);
if (string3 == NULL) {
    // handle out of memory
}
sprintf(string3,"%s%s%s",string1,stringX,string2);
...
free(string3);

答案 3 :(得分:4)

如果你需要string3,你需要为malloc分配空间,如果你需要它在堆上,或者如果不需要,则将其声明为字符数组。

答案 4 :(得分:0)

假设您将i定义为int i;在此级别,您告诉我将存储integer number,但是i变量中仍然没有有意义的数字。 这样,当您定义char *string3时,您会告诉string3将存储char指针,但仍然没有有意义的地址。因此必须为该变量分配内存

string3 =  malloc(strlen(string1)+strlen(stringX)+strlen(string2)+1);