我对字符指针及其工作方式不太清楚。
该程序可以构建,但是当我运行它时会崩溃。
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));
然后sprintf
,只要您使用malloc
. 注意:+ 1
用于空终止符。
或者,您可以ab
通过将其声明为数组来获取一些内存:
char ab[NUM_CHARS + 1];
如果不为 分配内存ab
,sprintf
调用将尝试写入NULL
,这是未定义的行为;这是你崩溃的原因。
您需要为数据分配内存。确实sprintf
需要char*
,但它不会为您分配内存。
第一行工作正常,因为编译器会自动为编译时定义的字符常量表分配数据。
与 inJava
或其他高级语言不同,该C
库的许多字符串函数不简单地设置字符串引用,而是在称为字符数组的预分配内存块上进行操作。
您的第一行是说ab
指向一个不存在的内存位置。
如果不是你这样做,你会有更多的运气char *ab = NULL;
:
char ab[12];
或者:
char *ab = (char*)malloc(12);
你可以这样做
char ab[10]; //allocate memory
sprintf(ab, "abc%d", 123);
"ab" 为空并且 sprintf 正在尝试写入它,您必须先分配它。
char ab[20];
sprintf(ab, "abc%d", 123); //
或者
char * ab = malloc(20); // new, whatever
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 或某个数字的数组,这些数字通常会涵盖我的大部分字符串长度情况。然后我将 char 指针用于对数组进行操作的函数。