В чем разница между этими двумя способами увеличения указателей для двумерного массива в C? - PullRequest
1 голос
/ 24 февраля 2020

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

Я написал функцию, которая применяет фильтр к изображению .bmp. Внутри функции я выделил память через mallo c () для хранения каждого пикселя с новым значением. После того, как я закончу sh, я хочу назначить новые значения исходным пикселям с помощью указателей. Я попробовал два способа сделать это, один работает, а другой нет, но я не понимаю разницу.

Здесь я объявляю два указателя:

RGBTRIPLE *copy = malloc(height * width * sizeof(RGBTRIPLE)); //RGBTRIPLE is the pixel struct
if (copy == NULL)
{
    fprintf(stderr, "Memory allocation error\n");
    exit(2);
}
RGBTRIPLE *rgb = &image[0][0]; // this points to first element of original image

Вот два метода, которые я пытался присвоить новым значениям. Не работает следующее:

int i;
for (i = 0; i < (height * width); i++)
{
    *rgb = *copy;
    rgb++;
    copy++;     
}
free(copy);
return;

Это работает:

int i;
for (i = 0; i < (height * width); i++)
{
    *((RGBTRIPLE *)rgb + i) = *((RGBTRIPLE *)copy + i);
}
free(copy);
return;

Почему?

Ответы [ 2 ]

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

Для любого указателя или массива p и индекса i выражение *(p + i) равно точно , равно p[i].

Это означает, что ваш второй l oop на самом деле

int i;
for (i = 0; i < (height * width); i++)
{
    rgb[i] = copy[i];
}

Я полагаю, что приведенная выше версия более ясна о том, что происходит и почему это работает.


Проблема с первым l oop заключается в том, что вы изменить и rgb и copy, чтобы вы потеряли оригинальные указатели. Вам нужно использовать временные указатели, чтобы он работал:

int i;
RGBTRIPLE *temp_rgb = rgb;
RGBTRIPLE *temp_copy = copy;
for (i = 0; i < (height * width); i++)
{
    *temp_rgb = *temp_copy;
    temp_rgb++;
    temp_copy++;     
}

// Here the original values of rgb and copy still exists
1 голос
/ 24 февраля 2020

В первом коде, когда вы достигнете здесь:

free(copy);

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

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