C печать адреса указателя на проблему с массивом - PullRequest
0 голосов
/ 24 февраля 2020

Когда я запускаю следующий код:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int array[100];
    int (*array_ptr)[100];
    void *buff = malloc(500);
    int *ptr;
    printf("array: %p \narray+1: %p\n", array, array+1);
    printf("array_ptr: %p \narray_ptr+1: %p\n", array_ptr, array_ptr+1);
    printf("buff: %p\n", buff);
    printf("ptr: %p\n", ptr);
}

результат выглядит следующим образом:

array: 0x7fffe6dc6bd0
array+1: 0x7fffe6dc6bd4
array_ptr: (nil)
array_ptr+1: 0x190
buff: 0x1f80260
ptr: 0x7fffe6dd417c

Я запускаю его несколько раз, array, array+1, buff и ptr все изменяют значения случайным образом, но array_ptr и array_prt+1 никогда не изменяются, хотя арифметика указателя c result 0x190 соответствует ожидаемой.

Указывает ли это, что массив, на который указывает array_ptr, хранится в куче? Но предполагается, что динамически распределенный блок памяти, на который указывает buff, находится в куче, и его значение изменяется, почему это так? Спасибо!

Ответы [ 2 ]

1 голос
/ 24 февраля 2020

array_ptr является неинициализированным указателем и получает неопределенное значение (в вашем случае 0).

array_ptr+1 равно sizeof (int) * 100 = 400 = 0x190 больше, чем array_ptr

ptr также является неинициализированным указателем, который в вашем случае указывает на мусор.

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

На ваш вопрос, array находится в стеке, buff находится в куче, а ptr / array_ptr неинициализированы, что приведет к ошибке мусора или сегментации, если вы попытаетесь получить доступ к их данным

0 голосов
/ 24 февраля 2020

Указывает ли это, что массив, на который указывает array_ptr, хранится в куче?

Нет. array_ptr не указывает ни на что, ни в стеке, ни в куче.


int (*array_ptr)[100];

array_ptr - это один указатель на массив из 100 int объектов, но с помощью этого оператора вы не создаете массив с 100 int объектами, по которым array_ptr указывает на первый элемент этого массива. Он создает только сам указатель.

С:

printf("array_ptr: %p \narray_ptr+1: %p\n", array_ptr, array_ptr+1);

Вы пытаетесь распечатать адреса объектов указателя array_ptr и его смещение на 1 точку, но это не так Это возможно, поскольку array_ptr не инициализируется, чтобы указывать на такие объекты. Таким образом, вы получите любой вид неопределенного поведения / непредсказуемые результаты.

Вам нужно инициализировать array_ptr с, например, адресом первого int объекта array :

int (*array_ptr)[100] = array;

То же самое относится к указателю ptr с:

printf("ptr: %p\n", ptr);

ptr должен иметь адрес объекта, на который он указывает, чтобы показать адрес этого объекта.

Но динамически выделенный блок памяти, на который указывает buff, также должен находиться в куче, и его значение изменяется, почему это так?

Это это совершенно другая вещь. С malloc вы do выделяете память в куче (если она была успешной, конечно), и вы do получаете указатель на эту память обратно, что не имеет место с int (*array_ptr)[100];.

...