我有一个程序
void swap(char **s1,char **s2);
int main()
{
char *list[] = {
"Das",
"Kannan",
"Rajendran",
"Shahul"
};
printf("Before swap list[0] = %s,list[1] = %s\n",*list[0],*list[1]);
swap(&list[0],&list[1]);
printf("After swap list[0] = %s,list[1] = %s\n",*list[0],*list[1]);
return 0;
}
void swap(char **s1,char **s2)
{
char *t;
t = *s1;
*s1 = *s2;
*s2 = t;
}
我正在尝试交换list [0]和list [1]的地址。
Visual Studio 2008在运行(开始调试)此程序时生成错误。 产生的错误是
ConsoleApp.exe中0x1029984f(msvcr90d.dll)的未处理异常:0xC0000005:访问冲突读取位置0x00000044。
没有编译错误。
我可以知道为什么指针使用指针不能正常工作。
也想知道原因
void swap(char *s1,char *s2)
也没用。
答案 0 :(得分:3)
您的打印输出有问题。删除星号:
printf("Before swap list[0] = %s,list[1] = %s\n",list[0],list[1]);
swap(&list[0],&list[1]);
printf("After swap list[0] = %s,list[1] = %s\n",list[0],list[1]);
为什么呢?好吧,list[0]
是字符"Das"
,其类型为char *
。这就是你要传递给printf的东西。如果您使用星号取消引用该指针,则最终将第一个字符'D'
传递给printf,其中printf期望char *
字符串。它最终试图将字符'D'
视为指针。 'D'
的ASCII值为68,或十六进制为0x44,因此可以解释您收到的错误消息。
使用该功能,您可以在两个字符串中交换字符,但是您无法自己交换字符串。将交换函数视为需要指向要交换的对象的指针。如果你交换两个整数,你就有swap(int *i1, int *i2)
。您想要交换两个类型char *
的字符串,这意味着交换函数需要两个星:swap(char **s1, char **s2)
。这有意义吗?
答案 1 :(得分:0)
问题出在你的printf语句中。您正在取消引用您的字符串指针。从以下位置更改printf:
printf("Before swap list[0] = %s,list[1] = %s\n",*list[0],*list[1]);
为:
printf("Before swap list[0] = %s,list[1] = %s\n",list[0],list[1]);
(以及后交换一个),一切都会很好。
答案 2 :(得分:0)
printf("Before swap list[0] = %s,list[1] = %s\n",*list[0],*list[1]);
swap(&list[0],&list[1]);
printf("After swap list[0] = %s,list[1] = %s\n",*list[0],*list[1]);
您无需在此处取消引用这些char *
。相反,你应该这样做:
printf("Before swap list[0] = %s,list[1] = %s\n",list[0],list[1]);
swap(&list[0],&list[1]);
printf("After swap list[0] = %s,list[1] = %s\n",list[0],list[1]);
您的list
数组包含char *
个元素,其中char *
元素是指向C字符串的指针(空终止字符序列)。通过解除引用它,您实际上是将每个字符串的第一个字符传递给printf
,而不是字符串本身。当printf
本身尝试取消引用该字符值时,会导致它尝试访问无效的内存段,从而导致分段错误。