c - 为什么 sprintf 中的第一个参数不能是 C 中的 char 指针
问题描述
我想将整数转换为字符串。这是有效的:
int main() {
int a= 54734;
char a_str[10];
sprintf(a_str, "%d", a);
printf("%s\n", a_str);
return 0;
}
但这不起作用:
int main() {
int a= 54734;
char* a_str;
sprintf(a_str, "%d", a);
printf("%s\n", a_str);
return 0;
}
它返回:
Process finished with exit code 139 (interrupted by signal 11:
SIGSEGV)
我认为字符串是空终止的,所以指向 char 的指针也应该可以工作。因为我是C新手,所以如果我错了,请纠正。
解决方案
首先,要了解的重要一点是,当您的程序尝试使用不允许使用的内存时,通常会发生分段错误。
其次,你必须了解sprintf
正在做什么。当您调用时sprintf(a_str, "%d", a)
,您将变量的内容移动到指向的地址处a
的内存空间。因此,为了不导致分段错误,您的程序必须“拥有”指向的内存,然后才能在.a_str
a_str
sprintf
当您传入 时char a_str[10]
,它始终有效,因为程序已为(使用行)sprintf
分配了自己的内存空间。因此,当您使用它时,程序正在访问它允许访问的内存。a_str
char a_str[10];
sprintf
但是,当您传递char* a_str
into时sprintf
,您会导致未定义的行为。当您创建 时char* a_str
,您所做的只是创建一个char
指向内存中某个随机位置的指针;您的程序很可能无法访问此随机指针指向的位置的内存。因此,调用sprintf
并尝试将其内容移动a
到其中会引发分段错误。如果您char* a_str
使用类似malloc
.
推荐阅读
- php - PHP - 将 JSON 文件(数组)拆分为多个文件
- spring - Spring JMS - 如何定义连接代理
- java - PostgreSQL 中存储为 JSONB 的 ZoneDateTime 的序列化格式
- python - 带有微秒计时器的时钟
- vba - 打开工作簿的计时器 - VBA
- three.js - 围绕枢轴点/轴扭曲/弯曲所有顶点(Three.js / GLSL)
- c# - 按字母顺序排序,先按字母顺序排列,先按字母顺序排列,然后按字母顺序排列。
- javascript - Array.push() 没有按预期工作
- ios - AirPlay:连接到 Apple TV 时音量控制被禁用
- linux - 容器中的 Docker“权限被拒绝”