Я пытался экспериментировать по вызову указателями. Но я столкнулся с ошибкой сегментации - PullRequest
0 голосов
/ 21 февраля 2020

Я пытаюсь разыменовать переменную-указатель x с переменной-указателем t, объявленной в функции s(int *x,int *y)? Если я использую тип данных t как целочисленный, а не как указатель на целое число, он работает нормально. Я не могу найти logi c, почему он дает ошибку сегментации при переходе к переменной указателя.

#include<iostream>
using namespace std;
void s(int *x,int *y)
{
    int *t;
    *t=*x;
    *x=*y;
    *y=*t;
}
int main()
{
    int a=3,b=5;
    s(&a,&b);
    cout<<" a:"<<a<<" b:"<<b<<endl;
    return 0;
}


вывод:

Segmentation fault                                                                                                            


...Program finished with exit code 139                                                                                        
Press ENTER to exit console. 


Ответы [ 4 ]

2 голосов
/ 21 февраля 2020
    int *t;
    *t=*x;

Говорит:

  1. Дайте мне достаточно памяти, чтобы держать указатель на int и вызывать этот указатель t
  2. Скопируйте значение, хранящееся в памяти указывается x в память, на которую указывает t.

Вопрос: куда указывает t? Мы не знаем Это неинициализировано. Использование неинициализированных значений плохо, а поведение не определено. Если вам повезет, вы получите segfault. Если вам не повезло, программа продолжает работать так, как будто ничего не произошло, до тех пор, пока через 2 недели не произойдет сбой корпоративного приложения с 1 000 000 строк кода.

См .: https://en.cppreference.com/book/uninitialized

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

похоже, что вы пытаетесь использовать функцию подкачки, чтобы поменять значения двух переменных, а "s" - это ваша функция подкачки. В этом случае вы должны кодировать следующим образом ..

#include<iostream>
using namespace std;
void s(int *x,int *y)
{
    int t;
    t=*x;
    *x=*y;
    *y=t;
}
int main()
{
    int a=3,b=5;
    s(&a,&b);
    cout<<" a:"<<a<<" b:"<<b<<endl;
    return 0;
}

В исходном коде вы ссылаетесь на t, не инициализируя его. Отсюда и ошибка сегментации. Однако для свопинга указатель t не нужен.

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

t не выделяется, поэтому, когда вы делаете *t = *x, это «неопределенное поведение». Хорошо, что ваш код дает сбой, потому что иногда он может работать (с UB все может случиться). Вместо этого выполните следующие действия, чтобы избежать бесполезного динамического распределения памяти c.

int t = *x;
*x = *y;
*y = t;
0 голосов
/ 21 февраля 2020

Вы никогда не выделяете память для вашего int указателя

В C ++ указатели должны выделять свою память из свободного хранилища вручную, в противном случае они указывают на несуществующий - нулевой размер (ну, на самом деле, размер указателя) ) - место в памяти. Поскольку вы не выделили место для указателя int, чтобы указать на него, при попытке получить доступ к этому расположению возникает ошибка по умолчанию.

Вам необходимо выделить для него память с помощью new. Пример:

int* t = new int(1);

Затем вам нужно удалить вместе с ним delete

delete t

Я бы взял книгу по C ++ и указатели, прежде чем идти дальше

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