我在这里得到了这个小小的程序,它带有预先分配的'计数'数字,然后将其解析为&x; xxx'的格式,其中x是0或相应的密码(例如,从' 6'我得到006,从234得到234)。当我这样得到它
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
int count = 0;
char number[2] = {0};
int base0 = count % 10;
int base1 = ((count % 100) - base0) / 10;
int base2 = ((count % 1000) - base1) / 100;
sprintf(number, "%d%d%d", base2, base1, base0); //print into the number variable
printf("%s\n", number);
}
一切正常,但如果我切换号码&#39;变量定义与
char* number = NULL;
我得到分段错误。这是为什么?它应该只指向字符串的开始。
答案 0 :(得分:0)
&#34;一切正常,&#34;
等一下。您已经严重缺乏所需的内存。在
的情况下 sprintf(number, "%d%d%d", base2, base1, base0);
number
需要更多的内存才能保持在界限范围内,因此,您的程序通过访问超出范围的内存来调用undefined behavior。您需要分配足够的内存来保存number
所持有的最终 sting 。
无论如何,NULL
被定义为无效的内存位置,访问再次调用UB,因此您无法使用它来存储任何内容
答案 1 :(得分:0)
NULL
是一个明确定义的“无处” - 它是一个无效的指针值,保证不会指向内存中的函数或对象。当您将number
设置为NULL
时,您说number
并未指向任何有意义的内容。
尝试处理无效指针会导致未定义的行为 - 在本例中为segfault。
数组和指针不相同的东西。在大多数情况下,数组表达式将“衰减”(转换)为指针类型,但对象始终是一个数组。
答案 2 :(得分:0)
在C中,字符串表示为字符数组;这条线
char number[2] = { 0 };
因此定义了一个用两个空字符初始化的两个字符数组('string')。
数组是一系列连续的(彼此相邻的)内存块,每个内存块都可以通过下标运算符(方括号)单独访问。
当您将上述行更改为
时char* number = NULL;
您不再定义字符数组。在这种情况下,您现在定义了一个指向char
变量的指针。因为数组基本上是彼此相邻的内存块,所以如果你知道第一个元素在哪里,那么就可以找到其他任何元素。因此,由于deference运算符允许您访问指针指向的值,因此您可以使用
*(char + i)
在C中完全等同于
char[i]
现在在你的情况下,你没有将char *设置为指向包含真实字符串的实际内存,你已经分配了NULL指针,这意味着'this指针指向任何地方'。将char *作为字符串处理需要将其解除引用(在指针之后);但是,取消引用NULL指针是一种未定义的行为,在这种情况下会导致seg错误
答案 3 :(得分:0)
字符数[2];为数字提供两个字节的内存 char * number = null;为* number提供零字节的内存。
当您执行sprintf时,您将在该数字中写入三个字节。 当说&#34; char * number = null&#34;时,你写入null,这会导致段错误。
当您执行sprintf时,您将3个字节写入已分配内存的2个字节 - 您将1个额外字节覆盖到堆栈中。