C语言中的字符指针初始化

C语言中的字符指针初始化,c,string,pointers,char,C,String,Pointers,Char,我不太清楚字符指针和它们是如何工作的 程序生成,但运行时崩溃 char *ab = NULL; //ab = "abc123"; // works fine sprintf(ab, "abc%d", 123); // this line seems to crash the program 当sprintf将(char*str)作为第一个参数时,我不明白这怎么可能是错误的 有人能给我解释一下吗?您没有分配内存用于ab 第一个赋值之所以有效,是因为您正在为ab赋值一个字符串常量:“abc1

我不太清楚字符指针和它们是如何工作的

程序生成,但运行时崩溃

 char *ab = NULL;
 //ab = "abc123"; // works fine
 sprintf(ab, "abc%d", 123); // this line seems to crash the program
当sprintf将(char*str)作为第一个参数时,我不明白这怎么可能是错误的


有人能给我解释一下吗?

您没有分配内存用于
ab

第一个赋值之所以有效,是因为您正在为
ab
赋值一个字符串常量:
“abc123”
。常量字符串的内存由编译器代表您提供:您不需要分配此内存

在将
ab
与例如
sprintf
一起使用之前,您需要使用
malloc
分配一些内存,并将该空间分配给
ab

ab = malloc(sizeof(char) * (NUM_CHARS + 1));
然后,只要您使用
malloc
留出足够的空间,您的
sprintf
就可以工作。注意:
+1
是用于

或者,您可以通过将
ab
声明为数组来为其创建一些内存:

char ab[NUM_CHARS + 1];

在不为
ab
分配内存的情况下,
sprintf
调用将尝试写入
NULL
,这是未定义的行为;这就是导致崩溃的原因。

您需要为数据分配内存。实际上,
sprintf
需要
char*
,但它不会为您分配内存


第一行工作正常,因为编译器会自动为编译时定义的常量字符表分配数据。

Java
或其他更高级语言不同,许多
C
库的字符串函数不只是设置字符串引用,相反,它们操作一块预先分配的内存,称为字符数组

第一行是说
ab
指向一个不存在的内存位置

如果不是
char*ab=NULL,而是您执行了以下任一操作:

char ab[12];
或:

你可以这样做

char ab[10];  //allocate memory
sprintf(ab, "abc%d", 123);
“ab”为空,sprintf试图写入它,您必须首先分配它

char ab[20];

sprintf(ab, "abc%d", 123); //


这里有几件事需要考虑。您的原始示例如下:

char *ab = NULL;
 //ab = "abc123"; // works fine
 sprintf(ab, "abc%d", 123); // this line seems to crash the program
char*ab=NULL
是指向字符的指针,初始化为NULL

我不认为
ab=“abc123”工作正常,除非它看起来像
char*ab=“abc123”。这是因为您将
char*ab
初始化为只读字符串。初始化可能发生在编译时

你的
sprintf(ab,“abc%d”,123)行失败,因为您没有提前为
char*ab
指针初始化任何内存。换言之,您没有执行以下操作:

ab = malloc((sizeof(char) * 3) + 1); /* + 1 allows for null string terminator. */

你可以用两种方法之一解决你的问题。可以如上所示分配动态内存,也可以将字符串设置为固定长度的数组,如char
ab[25]={0}。通常,我创建一个长度为1024、256或某个数字的数组,该数组通常覆盖大多数字符串长度大小写。然后我对数组上的函数使用字符指针。

新的,无论什么
都是无用的,因为它是C,而不是C++
sizeof(char)
保证是
1
(不要与
char\u位
混淆),所以没有必要。您还应该提到,您需要为后面的
'\0'
分配空间。
char *ab = NULL;
 //ab = "abc123"; // works fine
 sprintf(ab, "abc%d", 123); // this line seems to crash the program
ab = malloc((sizeof(char) * 3) + 1); /* + 1 allows for null string terminator. */