hagrawal: When you declare a struct (regardless of whether or not you're using typedef), no memory is actually allocated for it. You're only telling the compiler about the type of object you're creating.
The memory allocation only occurs when you actually create it. So, if you have your .h file in which you do:
typedef struct student
{
float grades;
char* name;
int id;
};
You're not actually allocating any memory until in your source file you actually create a variable of type struct. That's where the allocation takes place and it will be in the stack or the heap depending on whether you use malloc() or not.
The cs50 function GetString() actually allocates memory in the heap. That's what allows it to work without previously knowing how big the input is going to be.
Both int and int* will be allocated in the stack unless you use int* with malloc to allocate in the heap, but the pointer you create will still be on the stack. There's a difference, though, between char and char*, because when you do:
char* word = "hello";
The actual string literal "hello" is stored in the read only memory section. The variable "word" though, is just a pointer created in the stack that as a value, holds the address of the first element of the string.
Not sure what you're doing in your code. The first part declares an int "i" and assigns it a value of 10. The printf has two errors: first, since "i" is an int and not a pointer, you can't dereference it. If what you're trying to get is the address of the int, you should use the & operator and you should use %p as a placeholder.
The second one gives a segmentation fault because when you do
int* i2 = 10;
what you're actually doing is giving your i2 pointer the address 0x10. Remember that pointers store addresses, not values. When you try to dereference that pointer, you're trying to access some location in memory that you can't access. When you declare a pointer, you should always assign it the address of a variable as a value.
update:
hagrawal:
1 and 2) No, what i said is that GetString() allocates memory in the heap, and char* doesn't. If you do:
char* word = "hello";
you have to understand there's a difference between the actual char pointer "word", which is at the stack and is just a pointer, and the actual string literal "hello", which is at some address in the read only section of memory. That string literal will have its memory, in this case the size of 6 chars, and the address of the memory location of the first char 'h' is what the variable "word" stores.
If you do something like:
char* word = "hello";
printf("%p %p\n", word, &word);
you'll see you get two very different addresses: The first one is the actual address the pointer is pointing at (that is, the actual string "hello"). The second one is the address of the variable "word".
The read-only memory is a different section of the memory, not heap nor stack, and it's a section that doesn't allow changes (that's why you can't modify char* strings).
3) Not sure what you mean. There's no int i2 in your code as it is there.
""what you're actually doing is giving your i2 pointer the address 0x10. Remember that pointers store addresses, not values.". I am not sure if that's true because I can do int* i2 = 10; and then print some i2 which will give me 10."
What is to print "some i2"? You can either print the value stored in it, or its address. So yes, you can print its value, and it's going to be 10. Since i2 is a pointer, that value is a memory address. What else could you possibly store in a pointer? :)