Изменится ли адрес, на который указывает указатель, если мы изменим char * ptr =; - PullRequest
1 голос
/ 04 октября 2019
char* ptr = "hello";
ptr = "world";

Будет ли изменен адрес ptr?

Если я первоначально установил ptr = "hello", то я установлю ptr = "world". Куда девается "hello", он просто исчезает?

case 1:

[до изменения]

ptr = [h][e][l][l][o]; // address of ptr = 10001;

[после изменения]

ptr = [w][o][r][l][d]; // address of ptr still = 10001;

ИЛИ

дело 2:

[до изменения]

ptr = [h][e][l][l][o]; // address of ptr = 10001;

[после изменения]

ptr = [w][o][r][l][d]; // address of ptr still = 10002;
char* ptr = "hello";
ptr = "world";
// maybe 2 minutes later, i change again
ptr = "something else";

Ответы [ 3 ]

2 голосов
/ 04 октября 2019

Указатель изменится. Текст "привет" остается в памяти , но больше не доступен действительным способом.

#include <stdio.h>

int main(void)
{
    const char* ptr = "hello";
    printf("The value of ptr is %p\n", ptr);
    ptr = "world";
    printf("The value of ptr is %p\n", ptr);
}

The address of ptr is 0000000000404000
The address of ptr is 0000000000404020
0 голосов
/ 04 октября 2019

Переназначение указателя от &"hello"[0] до &"world"[0] явно изменит его значение. (&[0] просто делает явно неявное затухание массива явным).

Строковые литералы сохраняются в статической памяти только для чтения (= они имеют время жизни программы), а "hello" и "world" совершенно определенно не могут занимать одно и то же место, учитывая их различное содержимое.

Изменение указателя с "hello" на "hello\0world" может оставить значение указателя без изменений, поскольку тогда компилятор может объединить два строковых литерала в один ( 6.4.5p7 ).

Но нетиз моих установленных компиляторов (tcc, gcc, clang) это делает.

Для

#include <stdio.h>
int main()
{
    char *p;
    p = "hello";
    printf("%p\n", p);
    p = "hello\0world";
    printf("%p\n", p);
    p = "world";
    printf("%p\n", p);
}

Я получаю различные значения указателя, например:

0x55c30f718004
0x55c30f718014
0x55c30f71800e
0 голосов
/ 04 октября 2019

Если вы просто используете указатели напрямую, ОС назначит память для «привет» и «мир» в разных местах, и вы по существу измените указатель на эти разные адреса.

Таким образом, в случае 2 будет 3 разных местоположения для "привет", "мир" и "что-то еще", и указатель будет просто переназначен на третье место, когда вы выполните ptr = "что-то еще"

Также см .: Почему строка может быть назначена указателю char *, но не массиву char []?

...