2015-08-11 3 views
0

Я новичок в указателях. Для нижеприведенной программы я получаю ответ 255, а не 20. Пожалуйста, предложите, как исправить.Как решить ошибки указателя?

Вот код:

int sum(int *a , int *b); 
int main() 
{ 
    int *p; 
    int *q; 
    *p =10; 
    *q =10; 
    int c = sum(p,q); 
    printf("%d",c); 
} 
int sum(int *a , int *b) 
{ 
    return((*a)+ (*b)); 
} 
+0

Я тестировал его здесь. Я получил 20-символов: //ideone.com/B3M43p – ameyCU

+1

@ameyCU - это UB, чтобы установить указатель на произвольное значение, например '10', вы также могли бы получить рабочую игру packman, хотя Скорее всего, –

+0

@GlennTeitelbaum Да, конечно, это UB. Я просто указал, что у меня есть. – ameyCU

ответ

3

Eсть данные, то есть указатели. Для простоты, как только у вас есть данные, вы можете указать на нее. Это достигается с помощью оператора &. Для того, чтобы вернуться к данным из указателя, используйте оператор *, как у вас есть

Что-то больше похоже на

int sum(int *a , int *b); 
int main() 
{ 
    int p_data=10; 
    int q_data=10; 
    int *p =&p_data; 
    int *q =&q_data; 
    int c = sum(p,q); 
    printf("%d",c); 
} 
int sum(int *a , int *b) 
{  
    return((*a)+ (*b)); 
} 

EDIT: отметить также, что указатели могут быть использованы для доступа к памяти, выделенной из malloc, или mmap 'd или другими средствами

+0

thnks glenn..clears it for me :) – gabbar

+0

Это может быть достигнуто без использования 2 переменных, справа !!. – ameyCU

+1

@ameyCU да, но более конкретным является наличие переменных данных и переменных указателя перед абстрактной идеей пространства, выделенной из malloc. –

-2

Вы получаете 255 из-за случайной удачи. Я получаю 20, когда компилирую его, но это также случайная удача. Технический термин: «неопределенное поведение», и это не определено, потому что вы никогда не инициализировали указатели int *p и int *q.

Что находится внутри переменных указателя? Вы не знаете, я не знаю, никто этого не делает. Поскольку вы никогда не инициализировали их, их содержимое - все, что было до инициализации. Это все равно, что переехать в дом и получить какой-то барахл, оставшийся у вас предыдущие арендаторы.

Если содержимое указателей является адресом в памяти (и они не перекрываются), тогда возвращаемое значение должно быть 20 (случайным ударом). Но если один из них содержит нулевой адрес, кто знает, что вы получите!

Если вы хотите, чтобы получить 20 надежно, необходимо выделить память:

В C++:

int * p = new int; 
int * q = new int; 

В C:

int * p = (int*)malloc(sizeof(int)) 
int * q = (int*)malloc(sizeof(int)) 
+0

вы можете ответить на ваш вопрос – gabbar

+0

Я попал по ошибке –

+0

его помеченный 'c', включая C++, может быть запутанным –

3

Вам необходимо выделить память для указателей. Этот код должен работать:

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

int sum(int *a , int *b); 
int main() 
{ 
    int *p = (int*) malloc(sizeof(int)); 
    int *q = (int*) malloc(sizeof(int)); 
    if (p != NULL && q != NULL) 
    { 
     *p =10; 
     *q =10; 
     int c = sum(p,q); 
     printf("%d", c); 
     free(p); 
     free(q); 
    } 
    else 
    { 
     printf("Could not allocate enough memory"); 
     return 1; 
    } 

    return 0; 
} 

int sum(int *a , int *b) 
{ 
    return (*a) + (*b); 
} 

Надеюсь, это поможет!

+0

, если я получу это правильно, вы просто назначаете p и q некоторый случайный адрес в чтобы инициализировать указатели. – gabbar

+2

Просто точка, 'free' выделенная память. – ameyCU

+1

Да, я выделяю некоторые байты (количество, необходимое для представления int) в куче памяти, а затем я сохраняю там значение 10. –

0

Указатель - это переменная, которая содержит адрес другой переменной, и это кажется вам понятным. Но то, что кажется, все еще не очень ясно, что при создании указателя компилятор не автоматически создать также переменную, чтобы указать на ...

В коде:

int *p; 
int *q; 
*p =10; 
*q =10; 

Вы определяете p и q как указатели на int, но к каким переменным типа int они указывают? У них есть мусор внутри и может указывать в любом месте, поэтому при назначении 10 к тому, на что они указывают, на самом деле вы спам где-то в памяти.

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

Правильный код:

int sum(int *a , int *b); 

int main() 
{ 
    int i1, i2;  //Allocate 2 int variables 
    int *p = &i1; //Create pointers and assign them 
    int *q = &i2; //the address of int vars i1 and i2 
    *p =10;   //Initialize variables pointed by pointers with 10 
    *q =10; 
    int c = sum(p,q); 
    printf("%d",c); 
} 

int sum(int *a , int *b) 
{ 
    return((*a)+ (*b)); 
} 
0

Другой подход. Я думаю, что это может быть бесполезным для возврата функции, но он может помочь вам об указателях Это passing pointer to the sum function

#include <stdio.h> 

int sum(int *a , int *b); 
int main() 
{ 
    int p = 10; 
    int q = 10; 

    int c = sum(&p,&q); 
    printf("%d",c); 
} 
int sum(int *a , int *b) 
{ 

    return((*a)+ (*b)); 
} 
0

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

Вы пропустите те самые задания.

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

Таким образом, ваш результат мог бы быть только знаменитым 42.

Извлеченный урок: никогда не применяйте оператора к переменной, которая не была правильно инициализирована.

Смежные вопросы