为什么基本C代码会引发访问冲突

时间:2018-03-08 18:30:52

标签: c exception

我是C编程新手。我正在努力学习它。以下代码抛出访问冲突。为什么会这样?请解释一下。如何解决?

char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
printf("%s", arr[0]);

5 个答案:

答案 0 :(得分:6)

char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };
printf("%c", arr[0]);

%s表示打印所有字符,直到找到空值(将变量视为指针)。

%c表示只打印一个字符(将变量视为字符代码)

对一个字符使用%s不起作用,因为该字符将被视为一个指针,然后它将尝试在该内存之后打印该位置之后的所有字符,直到它找到空值。

答案 1 :(得分:2)

var a = [{a: 1, b: 2}, {a: 2, b: 2}, {a: 3, b: 2}] a.remove({a: 1}) a // Output => [{a: 2, b: 2}, {a: 3, b: 2}] 表示打印C字符串,而%s不是C字符串,而是一个字符,它是单引号分隔的字符。

最终发生的事情是你的'a'被解释为C字符串,但由于它没有正确终止NUL,程序会走到最后并进入无效内存,从而触发你的错误。

修复方法是使用arr打印单个字符,或终止数组:

%c

答案 2 :(得分:0)

%s用于char *,即'C - string',它需要空终止。在您的代码中,由于缺少空字符,您将获得错误,因为正在访问进一步的内存位置以查找NULL字符。

char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f', '\0' };
printf("%s", &arr[0]);

答案 3 :(得分:0)

%s格式说明符需要char *(字符指针)作为输入,它指向空终字符数组的开头。

arr本身可以被视为指向第一个元素的指针。 这意味着char arr[ <size> ]被视为char * const arr。 第一个示例中的差异为sizeof(arr),返回数组的实际大小(以字节为单位)。

可能的解决方案

char arr1[] = {'a', 'b', 'c', 'd', 'e', 'f'};
printf("%c%c%c%c%c%c\n", arr1[0], arr1[1], arr1[2], arr1[3], arr1[4], arr1[5]); /*please don't do this*/
printf("%*s\n", sizeof(arr1)/sizeof(arr1[0]), arr1); /*prints exact amount of characters*/
char arr2[] = {'a', 'b', 'c', 'd', 'e', 'f', '\0'};
printf("%s\n", arr2); /*explicit null termination*/
char arr3[] = "abcdef";
printf("%s\n", arr3); /*implicit null termination with string literal*/
const char *arr4 = "abcdef";
printf("%s\n", arr3); /*implicit null termination with string literal and pointertype*/

答案 4 :(得分:0)

%s转换说明符期望相应的参数具有类型char *并包含0终止字符串中第一个字符的地址。您正在获取访问冲突,因为'a'(ASCII 97)不是有效地址。

如果您要打印单个字符a,请改用%c转换说明符:

printf( "%c\n", arr[0] );

如果要打印arr中包含的字符串,首先必须添加终结符:

char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f', 0 }; // or "abcdef";

然后使用%s转换说明符并传递arr,如下所示:

printf( "%s\n", arr ); // or &arr[0], which does the same thing