为什么在指针指针中收集地址的交换程序不起作用?

时间:2009-12-25 07:16:32

标签: c pointers swap

我有一个程序

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) 也没用。

3 个答案:

答案 0 :(得分:3)

Visual Studio 2008在运行(开始调试)此程序时生成错误。

您的打印输出有问题。删除星号:

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,因此可以解释您收到的错误消息。

还想知道为什么void swap(char * s1,char * s2)也没有用。

使用该功能,您可以在两个字符串中交换字符,但是您无法自己交换字符串。将交换函数视为需要指向要交换的对象的指针。如果你交换两个整数,你就有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本身尝试取消引用该字符值时,会导致它尝试访问无效的内存段,从而导致分段错误。