2015-07-16 2 views
0

Я экспериментировал с указателями void, и я столкнулся с следующей проблемой. Когда я скомпилировал следующий код, все было в порядке, но когда я запустил его на своей машине, это не дало бы мне результатов вместо подсказки. Программа перестала работать (https://drive.google.com/file/d/0B1mLcnk8kTFUeEtmYnlOaWJ6T3c/view?usp=sharing), я не могу понять, что происходит за кулисами , есть ли какая-либо проблема в отношении разыменования указателя void.разыменование указателей void с литьем

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

#include<stdio.h> 
int main() 
{ 
    void* ptr; 
    int dupe = 5; 
    *(int*)ptr = dupe; // ptr = &dupe; 
     printf("The value at ptr is %3d",*(int*)ptr); 
} 

Я использую gcc на CodeBlocks.

+2

В строке 6 вы разыменования указателя который указывает нигде (он содержит нежелательный адрес), и вы пытаетесь поместить значение 'dupe' там (т.е. в никуда). – Sergey

+3

Обратите внимание, что '* (int *) ptr = dupe;' NOT 'ptr = &dupe;'. Второе задание абсолютно корректно и не вызывает неопределенного поведения. – Sergey

+0

Возможно ли, что при некоторой компиляции допустимый адрес нежелательной почты действителен? – BigO

ответ

1

Здесь вы пытаетесь разыменовать указатель, не выделяя ему память. Что вызывает segmentation fault или undefined behaviour.

int main(int argc, char *argv[]) 
{ 
    void* ptr; 
    int dupe = 5; 
    ptr = malloc(sizeof(dupe)); /* alloc memory for ptr */ 
    *(int*)ptr = dupe; 
    printf("The value at ptr is %3d",*(int*)ptr); 
    free(ptr); 
    return 0; 

} 

Если вы не планируете выделить память, то просто заменить *(int*)ptr = dupe; с ptr = &dupe в коде, так как теперь ptr будет указывать на правильное местоположение памяти переменной dupe.
См this для получения более подробной информации о неопределенном поведении

+1

'(int *) ptr' вызывает UB, используя неинициализированное значение указателя, даже если оно не разыменовано после –

+0

Итак, почему это работает, когда я использую прокомментировал код в строке 6 вместо оригинала, не используя malloc()? – BigO

+3

@BigO другой код отличается. Различные коды делают разные вещи. –

3
6.  *(int*)ptr = dupe; // ptr = &dupe; 

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

Заявление ptr = &dupe сделает точку ptr в ячейке памяти переменной dupe.

+1

Нашел ваш ответ полезным, но, увы! проблема репо для повышения. – BigO

1
1. void* ptr; --->ptr is a void pointer that means it can hold an address of any data type, but currently it is not pointing to any address. 
2. *(int*)ptr = dupe ---> ptr point to no where and you are trying to put a value which is not valid. 
3. ptr = &dupe; --> in this case ptr will point to address of dump which is a valid one. 
0

Указатель int *ptr, как правило, значение адреса, подобно количеству коробки. Здесь int - тип коробки, он намекает, что этот ящик предназначен для размещения int. Конечно, вы также можете бросить его для размещения других вещей, таких как (otherKindType*)ptr.
При попытке почерпнуть указатель с *ptr = someValue, как бы получить объект внутри коробки, вы должны пообещать, что он указывает на точное место.

Code1 (может работать):

#include<stdio.h> 
int main() 
{ 
    void* ptr; // ptr is a pointer, it should point to somewhere 
    int dupe = 5; // a box (named dupe) fitted for int which hold 5 
    ptr = &dupe; // ptr points to that box named dupe 
    printf("The value at ptr is %3d",*(int*)ptr); // get content inside the box 
} 

Кодекса2 (не работает):

#include<stdio.h> 
int main() 
{ 
    void* ptr;// pointer, point to a random place 
    int dupe = 5; 
    *(int*)ptr = dupe; // To put 5 to the box that pointed by ptr 
         // But now, ptr still points to a random place 
         // oops! To write to a random box is dangerous! 
         // It will cause error like `BUS error` 
         // Sometimes, to read a random box can output wired value. 
    printf("The value at ptr is %3d",*(int*)ptr); 
} 

Code3 (может работать):

#include<stdio.h> 
int main() 
{ 
    void* ptr; 
    int dupe = 5; 

    int new_box;//added   
    ptr = &new_box;//added, now ptr points to new_box   

    *(int*)ptr = dupe; // To put 5(content of dupe) to the box that pointed by ptr 
         // That is to put 5 to new_box 
    printf("The value at ptr is %3d",*(int*)ptr); // get content inside the box 
}