Download presentation
Presentation is loading. Please wait.
Published byKerry Andrews Modified over 9 years ago
1
Pointers, Heap Memory Rudra Dutta CSC 230 - Spring 2007, Section 001
2
Copyright Rudra Dutta, NCSU, Spring, 20072 Main Ideas Location, Address – Variables all have to be stored some“where” Address is a number – Can be stored as a value – Can be manipulated Can be used to implement call by reference Re-visit some issues with this view – printf, scanf – Arrays – Strings
3
Copyright Rudra Dutta, NCSU, Spring, 20073 Location of a Variable Address or location of a variable is a number – That number can be said to “point” to the variable – Address can itself be stored in a pointer variable – True whether memory is in heap or stack int i; something(int m) { float k; } main () { int i; for (i=0; i<3; i++) { something (i); }
4
Copyright Rudra Dutta, NCSU, Spring, 20074 Address Values C allows extracting address of any variable – Use operator & – Returns a value of type pointer – “Indirection” or “referencing” main () { int i; for (i=0; i<3; i++) { printf (“%x\n”, & i); }
5
Copyright Rudra Dutta, NCSU, Spring, 20075 Natural Questions What are typical value of an address for a variable on the stack, on the heap, global? – Programmer is not supposed to ask How large are the values? – Platform dependent – Must be reasonably large, since process virtual memory can be quite large – Can print out using %x or similar What about multi-byte variables? – Address points to first byte of storage
6
Copyright Rudra Dutta, NCSU, Spring, 20076 Pointer Variables Variables to store addresses of other variables – Typed to match variable pointed to – Can be “de-referenced” to access original variable Dereferencing operator - * – Unfortunately, same as multiplication Different precedence (see table on website) – Moreover, also used to define pointer variables int i; something(int *pm) { int *p_local; p_local = pm; *p_local = 25; } main () { int i; for (i=0; i<3; i++) { something (&i); } Dereferencing creates lvalue
7
Copyright Rudra Dutta, NCSU, Spring, 20077 Pointer Types Two possible views: – A pointer points to a particular variable, which has a type and hence a number of bytes required to keep it. So the pointer must be linked to that type. Or, “how would you know how to dereference?” – A pointer is a pointer is a pointer - it is a variable which holds the address of a particular byte (starting byte). Since the address of any byte is the same, all pointers require the same amount space to store, so there should just be one generic pointer type. Or, “how do you know what kind of pointer you have?” Both views represented in standard – Fundamentally first view (typed) – But generic pointers defined in ANSI standard (later)
8
Copyright Rudra Dutta, NCSU, Spring, 20078 Call By Reference The first does not work, the second does swap(int a, int b) { int temp; temp = a; a = b; b = temp; return; } swap(int *pa, int *pb) { int temp; temp = *pa; *pa = *pb; *pb = temp; return; }
9
Copyright Rudra Dutta, NCSU, Spring, 20079 Basic Pointer Access Examples Define a character variable c and two pointers p and q to point to it Point p to point to c Use p to write ‘a’ into c Point q to c using p Read out c using q What are the value of : – (*p == *q) – (p == q) – (&p == &q)
10
Copyright Rudra Dutta, NCSU, Spring, 200710 Pointer Definition Pitfall Pointer “types” are not really types – Definition parsed as starting with fundamental type – Need to be careful about multiple definitions on a line int *p; int *q; int* p; int* q; int *p, *q; int* p, q; An integer pointer p, an integer q
11
Copyright Rudra Dutta, NCSU, Spring, 200711 Address Arithmetic Address values are just numbers – Can be operated on (added, subtracted) Pointer variables just store addresses – Can be incremented, decremented Integers added or subtracted to pointer give: – Pointer values pointing to objects after or before – Incrementing a pointer points to the next object NOT next byte Pointer values subtracted from pointer values: – Number of objects between one and the other NOT number of bytes What is the meaning of such operations?
12
Copyright Rudra Dutta, NCSU, Spring, 200712 Address Arithmetic - Examples What makes sense? – Pointer value +/- integer value – Pointer value - pointer value What does not? – Pointer value + pointer value p int i; int *p; int *q; p = &i; printf (“%x\n”, p); p++; printf (“%x\n”, p); q = p + 3; printf (“%d\n”, q-p); pq int takes 2 bytes in example
13
Copyright Rudra Dutta, NCSU, Spring, 200713 Arrays Revisited Why would pointer arithmetic be useful? – One answer : arrays – (The other answer: heap memory - later) Defining an array always creates contiguous storage for the various array elements – Successive elements can be accessed by pointer increment In fact, there are no real arrays in C – An array definition creates memory and a pointer to the first element – This pointer is the “name” of the array
14
Copyright Rudra Dutta, NCSU, Spring, 200714 Pointer Access to “Arrays” Name of array is pointer to first element – Type of that pointer is pointer to element type Consider the definition int ia[30]; – ia is (just like) a variable of type int* The first element can be accessed as – ia[0] – *ia The second element can be accessed as – ia[1] – *(ia+1) In fact, there is no difference between the two – Compiler internally translates to pointer (address) access
15
Copyright Rudra Dutta, NCSU, Spring, 200715 Arrays are really Pointers int main () { int p[5], i; for (i=0; i<5; i++) { p[i] = i*i; } for (i=0; i<5; i++) { printf ("%d ", p[i]); } printf ("\n"); }
16
Copyright Rudra Dutta, NCSU, Spring, 200716 Arrays are really Pointers int main () { int p[5], i; for (i=0; i<5; i++) { p[i] = i*i; } for (i=0; i<5; i++) { printf ("%d ", *(p+i)); } printf ("\n"); }
17
Copyright Rudra Dutta, NCSU, Spring, 200717 Arrays are really Pointers int main () { int p[5], i; for (i=0; i<5; i++) { p[i] = i*i; } for (i=0; i<5; i++) { printf ("%d ", i[p]); } printf ("\n"); }
18
Copyright Rudra Dutta, NCSU, Spring, 200718 Arrays are really Pointers int main () { int p[5], i; for (i=0; i<5; i++) { p[i] = i*i; } printf ("%d ", 0[p]); printf ("%d ", 1[p]); printf ("%d ", 2[p]); printf ("%d ", 3[p]); printf ("%d ", 4[p]); printf ("\n"); }
19
Copyright Rudra Dutta, NCSU, Spring, 200719 Essential Difference in Definition How do the effects of these two differ? – int *p; – int p[5]; How do the effects of these two differ? – int p[] = {0, 1, 2, 3, 4}; – int p[5] = {0, 1, 2, 3, 4}; How do the effects of these two differ? – int p[]; – int p[5]; How do the effects of these two differ? – int *p; p = &i; – int p[5]; p = &i;
20
Copyright Rudra Dutta, NCSU, Spring, 200720 Array Access to Pointers It works the other way too Write code to print out the 5 integers in p – int p[5]; Simplify: – &p[3] – *&p[3] – *(p+(&p[5]-(p+3)))
21
Copyright Rudra Dutta, NCSU, Spring, 200721 Pointer Problems “Dangling” pointers – Pointers that do not point to anything in particular – Value stored in the pointer variable is “garbage” – May point to areas not accessible to programmer Dereferencing will cause program crash (even reading) – May point to somewhere inside process memory Dereferencing can cause unforeseen results
22
Copyright Rudra Dutta, NCSU, Spring, 200722 Dangling Pointers How do we get dangling pointers? – A pointer is dangling as soon as it is defined – Pointer with a broader scope (e.g. global) int main () { int *p, i; p = &i; printf (”%d\n", *p); } int *p; int something () { int i; p = &i; printf (”%d\n", *p); }
23
Copyright Rudra Dutta, NCSU, Spring, 200723 Strings Revisited There are no real strings in C – Strings are just shorthand for char arrays Special conventions: – Entire array can be literally quoted by the use of “” – End of “string” is indicated by a 0 value In character format, literally quoted as ‘\0’ - escape character Problematic question: where are literally quoted arrays located? – Literally quoted numbers are not any“where” but ephemeral values – Literal arrays must be in some memory - but treat as read-only (more later) h e l l o \0
24
Copyright Rudra Dutta, NCSU, Spring, 200724 String Example What happens? int main () { char str[10] = "hello"; int i; printf ("%s\n", str); for (i=0; i<10; i++) { printf ("%c ", str[i]); } Change array initialization to form not using special “string” convention - ?
25
Copyright Rudra Dutta, NCSU, Spring, 200725 String Example int main () { char str[10] = {'h','e','l','l','o','\0','1','2','3','4'}; int i; printf ("%s\n", str); for (i=0; i<10; i++) { printf ("%c ", str[i]); } str[0] = ‘c’; printf ("%s\n", str); } What happens if you supply too few literals ? – Rest initialized to zero
26
Copyright Rudra Dutta, NCSU, Spring, 200726 Character Type Functions It is easy to check whether a particular character is lowercase, numeric, etc.,… – Provided you know what the character set is (ANSI?) Standard library provides portable methods to check character types – Functions declared in ctype.h int isalnum(int c) is c an alphanumeric int isalpha(int c) is c an alphabetic letter int islower(int c) is c a lower case letter int isupper(int c) is c an upper case letter int isdigit(int c) is c a digit int isxdigit(int c) is c a hexadecimal digit int isodigit(int c) is c an octal digit
27
Copyright Rudra Dutta, NCSU, Spring, 200727 Character Type Functions int isprint(int c) is c printable (not a control character) int isgraph(int c) is c printable (not a space) int ispunct(int c) is c printable (not space or alphanumeric) int isspace(int c) is c whitespace int tolower(int c) return lowercase version of c int toupper(int c) return uppercase version of c
28
Copyright Rudra Dutta, NCSU, Spring, 200728 Example Given a pointer s to a string and an integer number n, return 0 if the string terminates in n -1 characters or less (that is any of the first n characters pointed to by s are ’ \0 ’ ), 1 if not. Examples: "platform" 8 - 1 "platform" 9 - 0
29
Copyright Rudra Dutta, NCSU, Spring, 200729 Formatted I/O Revisited Formatted printing - print the variables supplied as arguments (and literal text) – printf (“The %d-th entry is %f\n”, i, p[i]); – The 3-th entry is 3.14159 BUT, number of arguments is variable – (C provides specific syntax - later) – How does such a function know how many arguments, of what type? – Consider what happens to the stack Answer: first argument (must be present) must somehow communicate – Format string in printf performs this function
30
Copyright Rudra Dutta, NCSU, Spring, 200730 Formatted Input Provided as library function scanf – Two aspects of stack memory Use of format string just as in printf – First argument tells function the number of arguments that follow However, the job of scanf is to “read in” values – Logically, “Read in a decimal integer and store into the integer variable i” – Call by value does not allow modifying argument – Need to pass pointer - “call by reference” scanf (“%d”, &i);
31
Copyright Rudra Dutta, NCSU, Spring, 200731 Quick Examples Write scanf statements to: – Read in three decimal integer values into i, j, k – Read in a decimal integer into i, and a character into c – Read in a character into c, and a decimal integer into i – Read in two long integers separated by the text “ and ” into l1, l2
32
Copyright Rudra Dutta, NCSU, Spring, 200732 Two Uses of Format Each % in the format string indicates one formatting command, also implies a variable A %d in the format string: – Tells printf to print 4 as 4, not 4.000 or 4e0 – Tells scanf to stop reading when next character cannot be part of a printed decimal integer 44 is read as 44, 4 4 is read as 4 (next one left in stream) BUT also: – Tells printf to read the next argument from the stack to supply the value to print, and interpret as int – Tells scanf to write sizeof(int) bytes into the place pointed to by the next pointer, in int representation
33
Copyright Rudra Dutta, NCSU, Spring, 200733 Distinctions Whitespace – printf - whitespace in format string is just something literal to be printed to the output stream Objective is human readability – scanf - whitespace in input stream is something that indicates break between variables Whitespace in format string means “skip over literally” What about newline and tab? Conversions - mostly similar, but – scanf needs qualifiers for short, long, etc. What to store the value read in as – printf does not need - can provide to format output Knows from variable storage, and cannot be overridden
34
Copyright Rudra Dutta, NCSU, Spring, 200734 String I/O Remember - – String is just a char array, with null termination convention – Array is just contiguous variables, with array name pointer to first element printf has a special treatment for strings – With %s conversion, expects pointer to char – Also expects (prints until) null termination scanf has no special treatment (but seems to!) – Expects pointer, as always But now string name can be passed, no indirection – Also writes null termination after characters – Expects enough memory to write the whole string
35
Copyright Rudra Dutta, NCSU, Spring, 200735 Heap Memory General store of free memory – Programmer may request chunks of bytes, must manage use Memory is allocated from system – Allocation cannot be a language feature – Functionality made available through library Paired with facility to de-allocate - return memory to allocator Two widely used functions - malloc and free – Also calloc Important - cannot assume any ordering between chunks
36
Copyright Rudra Dutta, NCSU, Spring, 200736 General Use Use malloc or calloc to obtain chunks of free memory – Call may fail, check pointer value returned – calloc initializes to zero, malloc does not initialize – calloc takes two arguments – In general, best to use sizeof to specify size When use completed, use free to return chunk – Use free only with pointer values returned by malloc or calloc – Do not free from middle of an allocated block – Freeing creates dangling pointer Set to NULL after free - NOT automatic!
37
Copyright Rudra Dutta, NCSU, Spring, 200737 Examples p = malloc (2 * sizeof (int)); *p = 24; *(p+1) = *p+1; free (p); p = NULL; p = malloc (sizeof (int)); *p = 24; q = malloc (sizeof (int)); q = p; (*q)++; free (q); *p = 25; free (p); *p++ = (*p)++;
38
Copyright Rudra Dutta, NCSU, Spring, 200738 The void Type A type which is “nothing” – Storage-wise - nothing to store, so no bytes Functions may return void type – Retains function call discipline, but allows saying “this function does not return anything” – Equivalently, “the return value of this function occupies zero bytes on the stack” However, primary motivation comes from pointers and malloc A pointer is a pointer is a pointer - it is a variable which holds the address of a particular byte – Previously encountered question: how do you know what type of pointer you have?
39
Copyright Rudra Dutta, NCSU, Spring, 200739 Pointer Types Clearly, types of pointer variables (like all other variables) obtained from definition – Difference - does not affect amount of storage required for that variable itself, or interpretation of bytes Affects interpretation of location pointed to Better question: Can you know, just from the value of a pointer variable, what type it is pointing to? – Answer: No – Opens up possibility of interpreting one pointer type as another – NOT a pathological case - standard programming tool/trick How to convert? – Explicit casting, as usual – int *p; char *q; – q = (char *) p;
40
Copyright Rudra Dutta, NCSU, Spring, 200740 Generic Pointers Related question: What type of pointer should a function like malloc return? – Programmer’s purpose will differ on different calls – Used to be int *, programmer needed to cast each time Solution: define a “generic pointer” – Identifies a byte location in memory, but says nothing about how many bytes from there are being pointed to Size of “object being pointed to” is zero – Pointer to nothing - a void * pointer malloc etc. can and should return such pointers char *int *void *
41
Copyright Rudra Dutta, NCSU, Spring, 200741 The void * Type Specific rules with respect to void pointers Points to “nothing”, which implies – Such a pointer can never be de-referenced – Compiler does not know how many bytes to pull out, nor how to interpret More correctly, knows that number of bytes is zero Must make malloc simpler – Must not require casting of return type every time – Special rule: void * can be silently cast into other pointer types – Irony: programmer is never sure of portability, so ends up casting anyway
42
Copyright Rudra Dutta, NCSU, Spring, 200742 Read: Pointers – Chapter 5 – Sections 5.9 - 5.12 - later printf, scanf – Chapter 7 – Sections 7.3, 7.6 - later malloc etc. – man pages – Sections 7.8.5, optionally 8.7
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.