Указатель арифметический с массивом - PullRequest
0 голосов
/ 07 ноября 2018

Я пытаюсь написать простую программу на C, которая хранит элементы в указателе. Я получаю нежелательные значения при печати элементов массива.

Вот код:

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

#define MAX 5

int main(int argc, char const *argv[]) {

    int* a = (int*)malloc(MAX * sizeof(int));
    int* b = NULL;
    int* const maxAddress = a + MAX;

    if(a != NULL) {
        for(int index = 0; b = a, b < maxAddress; index++) {
            *(a + index) = index;
            printf("Value: %d, Index: %d\n", *(a + index), index);
            a++;
        } 
    }   

    printf("\n\n");

    for(int index = 0; index < MAX; index++) // Getting junk values here
        printf("Index: %d, Value: %d, Address: %p\n", index, *(a + index), a + index);

    return 0;
}

Ответы [ 3 ]

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

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

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

#define MAX 5

int main(int argc, char const *argv[]) {

    int* a = (int*)malloc(MAX * sizeof(int));
    int* b = a;
    int* const maxAddress = a + MAX;

    if (a != NULL) {
        for (int index = 0; b < maxAddress; index++) {
            *(a + index) = index;
            printf("Value: %d, Index: %d\n", *(a + index), index);
            b++;
        }
    }

    printf("\n\n");

    for (int index = 0; index < MAX; index++) // Getting junk values here
        printf("Index: %d, Value: %d, Address: %p\n", index, *(a + index), a + index * sizeof(int));

    return 0;
}
0 голосов
/ 07 ноября 2018

Синтаксис *(a + index) эквивалентен a[index]; последний более четко указывает на ваше намерение с кодом.

Если мы разберем то, что вы делаете, со строками index++ (в вашем объявлении цикла for) и a++ в теле вашего цикла, вы заметите, что обращаетесь к памяти, которую вы не делали ' т фактически выделить на a:

Итерация цикла # 0 (a = индекс выделенного адреса = 0):

*(a + index) accesses a[0]
a[0]   a[1]   a[2]    a[3]    a[4]
 0      ?      ?       ?        ?

Итерация цикла # 1 (a = alloc + 1 index = 1):

*(a + index) accesses a[2]
a[0]   a[1]   a[2]    a[3]    a[4]
 0      ?      1       ?       ?

Вы начинаете писать после массива на итерации № 3:

*(a + index) accesses a[6]
a[0]   a[1]   a[2]    a[3]    a[4]     | MEMORY NOT BELONGING TO a
 0      ?      1       ?       ?                   3?

Кроме того, после начального цикла for, в котором вы увеличивали указатель a до конца выделенной суммы, вы пытаетесь получить к нему доступ снова, не сбрасывая его к первоначальному значению, поэтому значения, к которым вы обращаетесь, даже не равны. те, которые ты (думал, что ты) назначил.

Это особенно плохо для памяти, выделенной с помощью malloc, поскольку вы обычно позже free это делаете, но вы не можете сделать это без указателя на начало выделенного блока памяти.

Решение:

Не увеличивайте a в вашем начальном цикле for и используйте правильное условие истинности:

for(int index = 0; (a + index) < maxAddress; index++) 
// Also valid: ...; index < MAX; ...
{
        *(a + index) = index;
        printf("Value: %d, Index: %d\n", *(a + index), index);
} 
0 голосов
/ 07 ноября 2018

У вас есть два независимых приращения. В цикле for вы делаете index++, а в конце цикла вы увеличиваете a++. Это означает, что ваша первая запись в a[0], ваша следующая в a[1 + 1] и т. Д. По сути, вы пропускаете все остальные элементы.

Чтобы избежать этого увеличения a или index, но не оба. Поскольку вы хотите, чтобы значения index прогрессировали, я бы порекомендовал удалить строку a++.

Переменная b не используется, кроме как в начале цикла, поэтому условие b = a, b < maxAddress кажется бессмысленным. Это может быть записано как a < maxAddress. Если бы я так предположил, b использовался в более полной версии кода, чтобы сохранить предыдущее значение a для следующей итерации.

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