Как использовать realloc () в функции и получить доступ к значениям? - PullRequest
0 голосов
/ 01 ноября 2019

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

Также код дает ошибку Ошибка сегментации (ядро сброшено)

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

void secValue(char **);

void main(){
    char *pointer=(char *)malloc(2*sizeof(char));
    char a;
    int i;
    printf("Enter 1st value \n");
    scanf(" %c",&pointer[0]);
    secValue(&pointer);

    //Display
    for(i=0;i<=3;i++){
        printf(" %c\n", pointer[i]);
    }
}

void secValue(char **pointera){
    printf("First value is %c \n",*pointera[0]);

    printf("Enter 2nd value\n");
    scanf(" %c",&pointera[1]);

    printf("Enter 3rd and 4th value\n");
    *pointera=(char *)realloc(*pointera,3*sizeof(char));
    scanf(" %c %c",&pointera[2],&*pointera[3]);
} 

Ответы [ 2 ]

1 голос
/ 01 ноября 2019

Это выражение

*pointera[0]

эквивалентно

*( pointera[0] )

и возвращает значение объекта типа char.

Вы можете переписать выражение как

( *pointera )[0]

, но результат для этого конкретного случая будет таким же, потому что pointera[0] и *pointera являются эквивалентными выражениями. Вы могли бы даже написать pointera[0][0] из **pointera.

Вот демонстрационная программа.

#include <stdio.h>


int main(void) 
{
    char c = 'A';
    char *p = &c;
    char **q = &p;

    printf( "c = %c\n", *q[0] );
    printf( "c = %c\n", ( *q )[0] );
    printf( "c = %c\n", q[0][0] );
    printf( "c = %c\n", **q );

    return 0;
}

Ее вывод

c = A
c = A
c = A
c = A

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

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

( *pointera )[i]

, где i - индекс требуемогоэлемент. Эта запись говорит читателю кода, что второй указатель ( *pointera ) указывает на первый элемент массива.

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

printf("First value is %c \n",*pointera[0]);

до следующего

printf("First value is %c \n", ( *pointera )[0]);

Что касается этого оператора

scanf(" %c",&pointera[1]);

, то используемое выражение уже недопустимо. Указатель pointera указывает на один объект (другой указатель), поэтому выражение pointera[1] указывает за пределы одного объекта. Вы должны написать

scanf(" %c", *pointera + 1 );

или

scanf(" %c", &( *pointera )[1] );

То же самое верно для этого утверждения

scanf(" %c %c",&pointera[2],&*pointera[3]);

Там должно быть либо

scanf(" %c %c", *pointera + 2, *pointera + 3 );

или

scanf(" %c %c",&( *pointera )[2],&( *pointera )[3]);

Кажется, в этом утверждении

*pointera=(char *)realloc(*pointera,3*sizeof(char));

есть опечатка. Вы имеете в виду

*pointera=(char *)realloc(*pointera, 4 * sizeof(char));
                                    ^^^

Также лучше использовать промежуточную переменную для перераспределения памяти, поскольку realloc может возвращать NULL, а исходный указатель pointera будет перезаписан NULL.

Так что функция может выглядеть как

void secValue(char **pointera){
    printf("First value is %c \n", ( *pointera )[0]);

    printf("Enter 2nd value\n");
    scanf(" %c", *pointera + 1 );

    printf("Enter 3rd and 4th value\n");

    char *tmp = realloc(*pointera, 4 * sizeof(char)); 

    if ( tmp != NULL )
    {
        *pointera = tmp 
        scanf(" %c %c",*pointera + 2, *pointera + 3 );
    }
} 
0 голосов
/ 01 ноября 2019

Вам нужно использовать &((*pointera)[1]) вместо &pointera[1], потому что второе выражение является адресом второго указателя в массиве pointera, а НЕ адресом вложенного указателя. Мы должны использовать круглые скобки из-за приоритета оператора.

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

Вы также должны исправить аргумент в realloc() вызове функции. Вы получаете доступ к третьему индексу массива, поэтому длина массива должна быть не менее 4.

Вы также должны вставлять вызовы getchar() после чтения каждого отдельного символа функцией scanf (), потому что scanf() оставляет символ \ n в стандартном вводеи следующий вызов scanf() с форматом% c будет читать символ новой строки вместо набранного вами символа.

Итак, весь ваш код исправлен, я пытался не изменять логику и даже имена:P

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

void secValue(char **);

int main() {
    char *pointer = malloc(2 * sizeof(char));
    char a;
    int i;
    printf("Enter 1st value \n");
    scanf("%c", &pointer[0]);
    getchar();
    secValue(&pointer);

    for(i = 0; i <= 3;i++) {
        printf("%c\n", pointer[i]);
    }
}

void secValue(char **pointera) {
    printf("First value is %c\n", (*pointera)[0]);

    printf("Enter 2nd value\n");
    scanf("%c", &((*pointera)[1]));
    getchar();

    printf("Enter 3rd and 4th value\n");
    *pointera = realloc(*pointera, 4 * sizeof(char));
    scanf("%c %c", &((*pointera)[2]), &((*pointera)[3]));
}

Приветствия, gjm

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