Что если строки пересекаются в памяти? - PullRequest
0 голосов
/ 17 ноября 2018

Скажем, мы делаем следующее:

char* pc1;
char* pc2;

И тогда мы можем сделать

pc1 = "STRING";
pc2 = "ANOTHERSTRING";

Мой вопрос в том, что если pc1 будет всего за 2 байта до pc2 в памяти и они сталкиваются?Почему мы можем установить строковый литерал для указателей и с бесконечной длиной, когда мы не можем знать, что они не сталкиваются / не перекрываются?

Редактировать: я хотел спросить только о том, что было сказано, если pc1, за 16 байт до pc2 в памяти, одновременно указывая на строку длиной 300 байт.Но указатели на самом деле указывают на строки, которые находятся где-то в памяти, поэтому мой вопрос ясен прямо сейчас, спасибо всем.Я специально не выбрал pc1 как суффикс pc2, но это похоже на другую историю.

Ответы [ 2 ]

0 голосов
/ 17 ноября 2018

Я думаю, вы можете быть смущены тем, что делают назначения для pc1 и pc2. Эти операторы не копируют содержимое указанной строки в область памяти, на которую указывают pc1 и pc2. Они изменяют область памяти, на которую указывают pc1 и pc2. Чтобы понять, что я имею в виду, давайте добавим немного больше в ваш код и сделаем его полноценной программой:

#include <stdio.h>

int main() {
    char* pc1 = NULL;
    char* pc2 = NULL;

    printf("pc1 pointing to location in memory: %p\n", pc1);
    printf("pc2 pointing to location in memory: %p\n", pc2);

    pc1 = "STRING";
    pc2 = "ANOTHERSTRING";

    printf("pc1 pointing to location in memory: %p\n", pc1);
    printf("pc2 pointing to location in memory: %p\n", pc2);
}

Теперь скомпилируйте и запустите это. Когда я делаю это на моей машине, я получаю следующий вывод:

pc1 pointing to location in memory: (nil)
pc2 pointing to location in memory: (nil)
pc1 pointing to location in memory: 0x5578b61a57b8
pc2 pointing to location in memory: 0x5578b61a57bf

pc1 и pc2 начинаются с указания на «ничто» (NULL или nil). Затем, после операторов присваивания, мы указали им разные места в памяти, которые содержат строки «STRING» и «ANOTHERSTRING» соответственно.

0 голосов
/ 17 ноября 2018

pc1 и pc2 являются указателями.Расположение памяти может быть примерно таким:

Address     Contents
1000        ANOTHERSTRING\0
1020        1007        pc1 variable
1024        1000        pc2 variable

Это показывает, что содержимое строк может перекрываться, но указатели все еще различны.

Причина, по которой это разрешено, заключается в том, что выВы не можете изменять строковые литералы.Поэтому вам не нужно беспокоиться об изменении содержимого строки, на которую указывает pc1, и которое влияет на значение pc2, или наоборот.

Обратите внимание, что это может произойти только при использовании указателейСтроковые литералы.Если вы это сделаете, совпадения не будет:

char pc1[] = "STRING";
char pc2[] = "ANOTHERSTRING";

Каждый из них представляет собой отдельный массив, а литералы - это просто их начальные значения.

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