Ваш первый пример - ошибка seg, потому что вы пытаетесь отменить ссылку на нулевой указатель, который вы создали с помощью строки:
int *i=0;
Вы не можете отменить ссылку на указатель, который ни на что не указывает и ожидает хороших событий. =)
Второй сегмент кода работает, потому что вы фактически назначили память для вашего указателя, используя malloc, который вы можете удалить из ссылки. Я думаю, что вы можете получить значения, отличные от нуля, в зависимости от памяти рядом с адресом, который вы выделили с помощью malloc. Я говорю это потому, что обычно значение int составляет 4 байта, а вы присваиваете только 2. При разыменовании указателя int он должен возвращать значение в виде int на основе указанных 4 байтов. В вашем случае, первые 2 байта - это то, что вы получили от malloc, а смежные 2 байта - все, что есть, что угодно, и что бы это ни было, будет обрабатываться, как если бы оно было int. Вы можете получить странное поведение, подобное этому, и вам следует распределить размер памяти, необходимый для типа, на который вы пытаетесь использовать / point.
(т.е. int *i = (int *) malloc(sizeof(int));
)
Если у вас есть указатель, указывающий на память правильного размера, вы можете установить следующие значения:
#include <stdlib.h>
#include <stdio.h>
int main (int argc, char *argv[])
{
int *i = (int *)malloc(sizeof(int));
*i = 25;
printf("i = %d\n",*i);
*i = 12;
printf("i = %d\n",*i);
return 0;
}
Редактировать на основании комментария:
Указатель указывает на память, а не на значения. При инициализации char *ptr="test";
Вы не присваиваете значение «test», вы назначаете адрес памяти, где компилятор помещает «test», который помещается в сегмент данных вашего процесса и доступен только для чтения. Если вы попытаетесь изменить строку «test», то, скорее всего, вы запрограммируете seg-fault. Что вам нужно понять о char *, так это о том, что он указывает на один (то есть первый) символ в строке. Когда вы отменяете ссылку на символ *, вы увидите только 1 символ и один символ. C использует строки, оканчивающиеся нулем, и обратите внимание, что вы не отменяете ссылку на ptr при вызове printf, вы передаете ему сам указатель, и он указывает только на первый символ. Как это отображается, зависит от формата, переданного в printf. Когда printf передается в формате «% c», он будет печатать односимвольные точки ptr, если вы передадите формат «% p», он напечатает адрес, на который указывает ptr. Чтобы получить всю строку, вы передаете '% s' в качестве формата. Это заставляет printf начинать с указателя, который вы передали, и читать каждый последующий байт, пока не будет достигнут ноль. Ниже приведен код, демонстрирующий это.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main (int argc, char *argv[])
{
// Initialize to data segement/read only string
char *ptr = "test";
printf("ptr points at = %p\n", ptr); // Prints the address ptr points to
printf("ptr dereferenced = %c\n", *ptr); // Prints the value at address ptr
printf("ptr value = %s\n", ptr); // Prints the string of chars pointed to by ptr
// Uncomment this to see bad behavior!
// ptr[1] = 'E'; // SEG FAULT -> Attempting to modify read-only memory
printf("--------------------\n");
// Use memory you have allocated explicitly and can modify
ptr = malloc(10);
strncpy(ptr, "foo", 10);
printf("ptr now points at = %p\n", ptr); // Prints the address ptr points to
printf("ptr dereferenced = %c\n", *ptr); // Prints the value at address ptr
printf("ptr value = %s\n", ptr); // Prints the string of chars pointed to by ptr
ptr[1] = 'F'; // Change the second char in string to F
printf("ptr value (mod) = %s\n", ptr);
return 0;
}