Почему не работает программа подкачки, которая собирает адреса в указателях на указатели? - PullRequest
0 голосов
/ 25 декабря 2009

У меня есть программа ниже

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;
}

Я пытаюсь поменять местами адреса из списка [0] и списка [1].

Visual Studio 2008 выдает ошибку при запуске (Начать отладку) этой программы. Сгенерирована ошибка

Необработанное исключение в 0x1029984f (msvcr90d.dll) в ConsoleApp.exe: 0xC0000005: расположение чтения нарушения доступа 0x00000044.

Нет ошибок компиляции.

Могу ли я знать, почему указатель на используемый указатель не работает должным образом. Также хочу знать, почему void swap(char *s1,char *s2) тоже не сработало.

Ответы [ 3 ]

3 голосов
/ 25 декабря 2009

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' как указатель. Значение ASCII 'D' равно 68 или 0x44 в шестнадцатеричном формате, что объясняет полученное вами сообщение об ошибке.

Также хочу знать, почему также не работает void swap (char * s1, char * s2).

С помощью этой функции вы сможете поменять местами символы в двух строках, но вы не сможете поменять местами сами строки. Думайте о функции подкачки, как о нуждающихся в указателях на объекты, подлежащие обмену. Если бы вы меняли два целых числа, вы бы получили swap(int *i1, int *i2). Вы хотите поменять две строки типа char *, что означает, что для функции подкачки нужны две звезды: swap(char **s1, char **s2). Это имеет смысл?

0 голосов
/ 25 декабря 2009
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 сам пытается разыменовать это символьное значение, он пытается получить доступ к неверному сегменту памяти, что приводит к ошибке сегментации.

0 голосов
/ 25 декабря 2009

Проблема в вашем утверждении 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]);

(и после свопа тоже) и все будет хорошо.

...