有谁能告诉我这里我做错了什么?为什么我的程序会出现段错误?
我想在string1
和string2
之间插入第三个字符串。
#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
答案 0 :(得分:26)
想象一下,你有一堆现金要放在公文包里。你需要什么?你必须衡量现金的大小,才能知道公文包的使用大小,而且你需要一个方便携带现金的手柄。
现金是你的字符串。公文包是内存空间。公文包句柄是指针。
strlen(string1) + strlen(string2) + strlen(stringX)
。
称之为“总计”。malloc(total+1)
string3
将所有这些拼凑在一起......
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);