В чём разница между * и [] при объявлении массива?

В функции strcpy элементы одного массива копируются в другой. Проблема в том, что при инициализации массивов в main при помощи указателя выдает segmentation fault

#include<unistd.h>
char    *strcpy(char *dest, char *src)
{
    int i;
    i = 0;

    while (src[i])
    {
        dest[i] = src[i];
        i++;
    }
    dest[i] = '\0';
    return (dest);
}

int main(void)
{
    char *a = "abc";
    char *b = "def";
    char *c;
    c = strcpy(a, b);
    while(*c)
    {
        write(1, c, 1);
        c++;
    }
}

Но если задавать массивы при помощи [], все работает (выводит def).

int main(void)
{
    char a[] = "abc";
    char b[] = "def";
    char *c;
    c = strcpy(a, b);
    while(*c)
    {
        write(1, c, 1);
        c++;
    }
}

Почему? Как реализовать не используя "[]"?


Ответы (1 шт):

Автор решения: Sergey

Ребята, не надо наводить тень на ясный день. :-) Версия компилятора тут абсолютно не причём. Просто думаем, что происходит. Итак объявляется указатель :

char *a = "abc";

А куда указывает этот указатель? На константу. А можно ли менять значение константы вот так:

dest[i] = src[i]; // dest[i] указывает на константу!!

Разумеется - нет! Иначе бы начали писать такие вот штуки:

int *iptr; 
iptr = &2; 
*iptr = 3;
printf("%d\n", *iptr);

Во что бы тогда превратилось программирование на С ?! А вот запись

char a[] = "abc";

Означает нечто совсем иное: выделяется память размером 4 байта, в эту память копируется (!) значение символьной константы "abc" и указателю a присваивается значение адреса первого элемента этого выделенного участка памяти. Поэтому операция

dest[i] = src[i]; // dest[i] указывает на переменную!!

вполне допустима.

→ Ссылка