Смущенные результаты: массив указателей в C - PullRequest
2 голосов
/ 11 июля 2011

Я написал небольшой фрагмент кода, чтобы проверить, работает ли массив указателей так, как я ожидал.Затем я получил этот проводной результат - после третьего назначения указателя, массив указателя все указывает на последнюю строку.Кто-нибудь может объяснить, что случилось?Спасибо.

#include <string.h>
#include <stdio.h>

main() {

    char *pstr[10];
    char p[10];
    char *s1 = "morning";
    char s2[10] = {'h','e','l','l','o'};
    char s3[10] = {'g','o','o','d'};
    int i = 0; 

    strcpy(p, s1);
    pstr[0] = p;
    printf("%s\n", pstr[0]);

    strcpy(p, s2);  
    pstr[1] = p;
    printf("%s\n", pstr[1]);

    strcpy(p, s3);  
    pstr[2] = p;
    printf("%s\n", pstr[2]);

    for (i = 0; i < 3; i++)
        printf("%s\n", pstr[i]);
}

Вывод из программы:

morning
hello
good
good
good
good

Ответы [ 6 ]

6 голосов
/ 11 июля 2011

Вы установили pstr[0], pstr[1] и pstr[2] равными p. И последнее, что записано в p, - это последовательность байтов "good". Итак, в конце вы печатаете p три раза.

4 голосов
/ 11 июля 2011

Все три указателя в массиве pstr указывают на одну и ту же ячейку памяти (p).

И поскольку вы несколько раз изменяете содержимое этой ячейки памяти с помощью вызовов strcpy, она будет содержать все, что было помещено туда последним.

В этом случае строка "good" была размещена там последней, так что именно на это будут указывать все три указателя в массиве pstr, и это будет многократно отображаться в цикле.

3 голосов
/ 11 июля 2011

Фундаментальная точка - массив памяти, на который ссылается p, может содержать только одну строку за раз.

Цикл в конце вашего кода будет всегда выводить одно и то же значение на каждой итерации, так как вы добавили каждую запись в массив pstr с одинаковым указателем p.

Если вы хотите видеть разные результаты на каждой итерации, вы должны указать pstr[0], pstr[1] и pstr[2] на разные области памяти.

2 голосов
/ 11 июля 2011

не только все записи массива являются p, но вы strcpy не используете строки с нулевым символом в конце. strcpy() необходимо, чтобы строки заканчивались нулем, иначе вы получите переполнение буфера с непредсказуемыми последствиями.

2 голосов
/ 11 июля 2011

pstr [0], pstr [1] и pstr [2] указывают на один и тот же массив из 10 символов p. Когда вы копируете каждую строку, вы изменяете содержимое массива p, но его адрес не меняется. Итак, после того, как вы скопировали последнюю строку в p, вы просто напечатали одно и то же три раза.

1 голос
/ 11 июля 2011

Простой, вы устанавливаете pstr[i]=p; бит p - адрес статического буфера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...