1 ece 3331 chapter 11 storage allocation and linked lists
TRANSCRIPT
1
ECE 3331
Chapter 11
Storage Allocation and Linked Lists
2
ECE 3331
Compile-Time & Run-TimeStorage Allocation
int n,
float x;
compile-time storage allocation:
storage is allocated at compile time before run time
Run-time storage allocation:
storage is allocated at run time
Use
malloc
calloc
3
ECE 3331
In C:Storage is allocated when variables are defined compiler-time
storage allocation…int abc;struct client clients[100];
program to run for all applications maximum size of definition has to be used
#define maxsize 200…float a[maxsize][maxsize];…
4
ECE 3331
malloc
int* ptr;
ptr = malloc (sizeof(int));
malloc( sizeof (datatype))
• returns a pointer to the allocated storage
• returns NULL if fails
Run-time allocation:
char* alpha;
int* num;
char r;
r=getchar();
if(r==‘c’)
alpha=malloc(sizeof(char));
else
num=malloc(sizeof(int));
5
ECE 3331
Allocate structure at run time
typedef struct complex {
float real;
float imag;
} Complex;
Complex* ptrc;
ptrc = malloc(sizeof(Complex));
ptrc -> real=3.14;
ptrc -> imag = 2.11;
free (ptrc);
6
ECE 3331
Run-time storage allocation (dynamic memory allocation)
dynamically allocate and deallocate memory when required
ptr = malloc ( number_of_bytes_to_be_allocated);
• ptr: if successful a pointer to the allocated storage if unsufficient memory is available null
ptr
• traditionally, malloc() returns the address of type pointer-to-char
ptr = malloc(n*sizeof(float));
7
ECE 3331
• number_of_bytes_to_be_allocated:
eg. 100 sizeof (datatype)
sizeof (variable)ptr = malloc ( 100);ptr = malloc (sizeof (int))
m=malloc( sizeof(complex1));
struct complex
{ float a; float b; }complex1;
8
ECE 3331
calloc
int *ptr1,*ptr2;
ptr1 = malloc(sizeof(int));
ptr2 = calloc(20,sizeof(int));
• Allocates 20 int storage cells• Returns the address of first cell• Returns NULL if fails
9
ECE 3331
Two ways to access storage
compile-time storage (name, pointer)int a, *a_ptr;a_ptr=&a;printf(“%d %d “, a, *a_ptr);
running-time storage (pointer only)
a_ptr = malloc(sizeof(int));
10
ECE 3331
Garbage
int* ptr;
ptr = malloc (sizeof(int));
*ptr =999;
ptr = malloc (sizeof(int));
*ptr = -777;
printf(“%d”, *ptr);
• Prints -777• The cell storing 999 cannot
be accessed (garbage)
Remedy
int *ptr1,*ptr2;
ptr1 = malloc (sizeof(int));
*ptr1=999;
ptr2 = malloc (sizeof(int));
*ptr2 = -777;
printf(“%d%d”, *ptr1,*ptr2);
11
ECE 3331
Release run-time storage
free(*ptr);
deallocate the space pointed to by ptr
ptr points to a block of memory previously allocated by calloc() or malloc()
int *ptr;…ptr = malloc (sizeof(int));…free(ptr);
12
ECE 3331#include <stdio.h> #include <stdlib.h> typedef int** Matrix; /* hide the int** data type */ void store( char* file, Matrix m1, Matrix m2, int n ), mult( Matrix m1, Matrix m2, Matrix m3, int n ), print( Matrix m, int n ), freeMatrix( Matrix m, int n ); Matrix createMatrix( int n ); main() { int n; char filename[ FILENAME_MAX ]; Matrix m1, m2, m3; /* prompt user for side and file name */ printf( "Matrix size and file name: " ); scanf( "%d %s", &n, filename ); /* create the matrices */ m1 = createMatrix( n ); m2 = createMatrix( n ); m3 = createMatrix( n ); if ( NULL == m1 || NULL == m2 || NULL == m3 ) { /* success? */ fprintf( stderr, "Insufficient storage. Exiting...\n\n" ); exit( EXIT_SUCCESS ); } store( filename, m1, m2, n ); /* read data into m1 and m2 */ mult( m1, m2, m3, n ); /* m3 = m1 * m2 */ print( m3, n ); /* print m3 */ freeMatrix( m1, n ); freeMatrix( m2, n ); freeMatrix( m3, n ); /* free storage for m1, m2, and m3 */ return EXIT_SUCCESS; }
13
ECE 3331
/* Create a matrix of side n, i.e., a matrix * that contains n x n int cells. */ Matrix createMatrix( int n ) { Matrix m; int i; m = ( Matrix ) malloc( n * sizeof ( int* ) ); if ( NULL == m ) return NULL;
for ( i = 0; i < n; i++ ) { m[ i ] = ( int* ) malloc( n * sizeof ( int ) ); if ( NULL == m[ i ] ) { freeMatrix( m, i ); /* avoid garbage */ return NULL; } } return m; }
14
ECE 3331
/* Free all storage associated with matrix m. */ void freeMatrix( Matrix m, int n ) { int i; for ( i = 0; i < n; i++ ) free( m[ i ] ); free( m ); }
15
ECE 3331
/* Multiply matrix m1 by matrix m2, storing the product in matrix m3, where all three matrices are n by n in size:
void mult( Matrix m1, Matrix m2, Matrix m3, int n ) { int i, j, k; for ( i = 0; i < n; i++ ) for ( j = 0; j < n; j++ ) { m3[ i ][ j ] = 0; for ( k = 0; k < n; k++ ) m3[ i ][ j ] += m1[ i ][ k ] * m2[ k ][ j ]; } }
16
ECE 3331
Linked Lists
Single linked list
Linked list
N1, N2,…, Nn nodes
plus address of N1
Nk node contains the address of N(k+1) node
Nn node (last) contains null
17
ECE 3331
Example
typedef struct cat {
char name[10];
struct cat* next;
} CAT;
CAT cat1,cat2,cat3
CAT *start,*ptr
strcpy(cat1.name,”abc”);
strcpy(cat2.name,”nbc”);
strcpy(cat3.name,”cbs”);
cat1.next=&cat2;
cat2.next=&cat3;
cat3.next=NULL;
start=&cat1;
ptr=start;
printf(“%s”, ptr-> name)
ptr=ptr -> next
printf(“%s”, ptr -> name)
• Prints• abcnbc
18
ECE 3331
Example-modified
typedef struct cat {
char name[10];
struct cat* next;
} CAT;
CAT* get_cat(void);
main()
{
CAT* start;
start=get_cat();
}
CAT* get_cat(void)
CAT *curr,*first;
int r;
curr = first =malloc(sizeof(CAT));
printf(“\n enter name:”);
scanf(“%s”,curr -> name);
printf(“\nadd another?(1=y,0=no)”);
scanf(“%d”,&r);
19
ECE 3331
Example-modified
while ( r ) {
curr -> next =malloc(sizeof(CAT));
curr = curr -> next;
printf(“\n enter name:”);
scanf(“%s”,curr -> name);
printf(“\nadd another?(1=y,0=no)”);
scanf(“%d”,&r);
}
curr ->next=NULL;
return first
• This modified code assigns storage at run time and does not require setting maximum number of storage cells. That is, the number of cells is flexible.
20
ECE 3331
Operations on Linked Listfind ptr of n-th node
typedef struct node {
int num;
struct node* next;
} NODE;
/* find the n-th node */
NODE* find_n(NODE* ptr, int n)
/* ptr is pointer to first node */{
if (n<1)
return NULL;
while (- - n && ptr != NULL)
ptr =ptr -> next;
return ptr;
}• Let n=2 and assume that we
have 3 nodes• --n =1 ptr not NULL• ptr = ptr ->next• --n = 0 return• ptr points to the second node
21
ECE 3331
Add a node to existing linked list
NODE* find_n(NODE* ptr, int n);
NODE* add_n(NODE* ptr, NODE* new, int n)
{
NODE pred;
if (n==1){
new ->next = ptr;
return new;
}
ptr = pointer to first node
new = pointer to new node to be added
n=position of the new node in the revised list
returns pointer to the first node
returns NULL if fails
22
ECE 3331
pred=find_n(ptr, n-1);
if(pred == NULL)
return NULL;
new ->next = pred -> next;
pred -> next = new;
return ptr;
}
Before
after
n-1 n
new
23
ECE 3331
Delete a node to existing linked list
NODE* find_n(NODE* ptr, int n);
NODE* del_n(NODE* ptr, int n)
{
NODE *pred, *old;
if (n==1){
old = ptr;
ptr =ptr -> next;
}
else
ptr = pointer to first node
n=position of the node to be deleted
returns pointer to the first node
24
ECE 3331
pred=find_n(ptr, n-1);
if(pred == NULL||pred->next ==NULL)
return ptr;
old = pred -> next;
pred -> next = old->next;
free(old)
return ptr;
}
n-1 n
old
25
ECE 3331
ELEE 3331 "Sample" Exam 2
I.(10pts)Select the best answer to each of the following concerning ANSI C and circle your choice.
A. Which type of variables are initialized to zero by the C compiler?
1. auto
2. register
3. local
4. internal
5. static
6. all variables are initialized to zero
Ans: 5
26
ECE 3331
B. Given the declaration
float x, *z=&x;
which scanf would successfully read a float value into x?
1. scanf(“%f”,x);
2. scanf(“%f”,z);
3. scanf(“%f”,*z);
4. scanf(“%f”,&z);
5. all of the above
Ans: 2
27
ECE 3331
C. The sizeof operator used with an array name will give
1. the number of elements declared to be in the array
2. the number of elements actually in the array
3. the number of bytes allocated to the array
4. the number of bits allocated to the array
5. the number of dimensions of the array
Ans: 3
28
ECE 3331
D. Given the following declaration
char t1[5]={‘a’},*t2=t1,*t3=“Lois”,*t4=“Rhoda Baggs”;
which of the following statements would be valid?
1. t1 = t3;
2. t2 = t3;
3. *t2 = t4; (there was a typo here, there was supposed to have been the * in front)
4. t3 = &t4;
Ans: 2
29
ECE 3331
E. If temp is a member of the structure weather and the statement
addweat = &weather;
has been executed, then which of the following correctly references temp?
1. weather->temp;
2. (*weather).temp;
3. addweat.temp;
4. addweat->temp;
Ans: 4
30
ECE 3331
II.(6pts)Short answer
1. Assuming the first value in the array s is contained in s[0], give two different notations for referring to the 3rd element of s.
s[2] *(s+2)
31
ECE 3331
2. Given the declaration: int x = 25, *y;
The statement *y = x;
results in an “access violation” error. Explain the problem and indicate how it could be corrected, assuming we want y to point to a different memory location than x.
no memory is allocated for what y points to so either precede with y=(*int)malloc(sizeof(int)); or declare separate variable and have z point to it first: {int z; y=&z;}
32
ECE 3331
III.Indicate the output that would be produced by each of the following. Consider each case separately.A.(6pts)#include <stdio.h>#include <string.h>#include <math.h> int k = 55;main( ){ int i = 1, j=4, m; int f(int ); m = f(i); printf("\n %d %d %d \n", j,m,k); } int f(int j) {static int k = 2; if(j<3) k+=f(j+1); return(k);}
output: 4 8 55
f(1)
k=2;
k=k+f(2)
return k;
f(2)
k=k+f(3)
return k;
f(3)
k=2
return k;
33
ECE 3331
B.(8pts)
#include <stdio.h>
main( )
{
float a[2][3] = {{3.1,7.4,2.8},{1.9,6.3,9.8}};
printf(“\n%f %f %f %f \n”,*(*(a+1)+1),*(*(a)+1),*(*(a+1)),*(*(a)+1)+1);
}
output: 6.3
3.1 7.4 2.8
1.9 6.3 9.8
* -- point to raw
**-- point to column
3.1
1.9
7.4
6.3
2.8
9.8
2222
2225
2222
2225
*a **a
7.4 1.9 8.4
*(a+1)
*(*a+1)
34
ECE 3331
C.(4pts)#include <stdio.h> #include <string.h>#include <math.h>
main( ) {
int n; float q1,q2; char u1[16], u2[16]; FILE *fptr; fptr=fopen(“merry.dat”,”r”); while((n=fscanf(fptr,"%f %15s = %f %15s", &q1,u1,&q2,u2))!=EOF) {
printf("%d %f %f %s %s \n",n,q1,q2,u1,u2); fscanf(fptr,"%*[^\n]");
} fclose(fptr);}
4 1.0 11.0 pole /2
merry.dat 1 pole = 11/2 yard one gram = 0.035 ounces 1 gallon equals 3.79 liters1 electron = 1/1837 photons
0 1.0 11.0 pole /22 1.0 11.0 gallon /2
4 1.0 1.0 electron /1837
Output:
35
ECE 3331D.(10pts)Show exact spacing for this output by filling in the grid below main( ) {char ch = 'X'; char st[ ]= "Hello World"; int k = 52; float f = 12.978; double d = -97.4583; printf("%3d and %7.2f%c\n",k,f,ch); printf("%-14.5s\n\n",st); printf("%8.2f",d); printf("%.2f%.2e",f,f);}
output cols: 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0line 1 _ 5 2 _ a n d _ _ _ 1 2 . 9 8 X _ _ _ _ _ _ _ _ _ _ _ _ _ _line 2 H e l l o _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _line 3 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _line 4 _ _ - 9 7 . 4 6 1 2 . 9 8 1 . 3 0 e + 0 1 _ _ _ _ _ _ _ _ _
36
ECE 3331IV.(15pts)Long IntegersSuppose the following declaration is available globally: struct longint {
int digit; int power; struct longint *next;};This template has been used in creating a linked list representation of large integers, where the pointer to the list "points" to the least significant digit. For example, the number 3,421,000,000 would be represented as
Write a C function whose prototype is: struct longint *bigger(struct longint *int1, struct longint *int2);which will accept pointers to the beginning of two large integer linked lists and return a pointer to the beginning of the list which represents the larger integer.
1 6 2 7 4 8 3 9start
37
ECE 3331
struct longint *bigger(struct longint *in1,struct longint *in2) {int n1=0,n2=0,i; struct longint *p1,*p2; p1 = in1; while(p1->next!=NULL) {n1++;p1=p1->next;} p2=in2; while(p2->next!=NULL) {n2++;p2=p2->next;} if(p1->power>p2->power)return in1; if(p2->power>p1->power)return in2; if(p1->digit>p2->digit)return in1; if(p2->digit>p1->digit)return in2;
38
ECE 3331
while(n1>=0&&n2>=0) {
p1=in1; for(i=0;i<n1;i++) p1=p1->next; p2=in2; for(i=0;i<n2;i++)p2=p2->next; if(p1->power>p2->power)return in1; if(p2->power>p1->power)return in2; if(p1->digit>p2->digit)return in1; if(p2->digit>p1->digit)return in2; n1--;n2--;
} if(n1<0&&n2>=0)return(in2); if(n2<0&&n1>=0)return(in1); if(n1<0&&n2<0) printf("\n values same\n"); return(in1);}
39
ECE 3331
V.(15pts)Cold SpotsSuppose that the following declarations are available globally:
struct citytemps { char city[35];
float temp[366];};struct coldcnts {
char city[35]; int count;};Suppose further that a data file named cold.dat has been prepared containing the names of each city in Texas, along with that city's minimum temperatures(in Fahrenheit) for each day of the past year. The name of each city starts on a new line and is terminated by a semicolon (;). Following the name are the minimum temperatures for that city. For example:Austin; 44 48 38 ...Beeville; 38 37 35 ...San Antonio; 51 49 40 ..
40
ECE 3331
Write a complete C program that will input the data into an array of type struct citytemps, where each array element corresponds to a city. Then create a new array of type struct coldcnts, consisting of the name of the city and the number of days that city's minimum temperature was at or below freezing. Do not include in this new array any cities which had all days above freezing. Then print this new array, one city per line.
#include <stdio.h>#include <string.h>struct citytemps {char city[35]; float temp[366];};struct coldcnts {char city[35]; /*not required*/ int count;};
41
ECE 3331main( ){FILE *fin,*fout; struct citytemps cities[500]; struct coldcnts freeze[500]; int i,j,k,nfrz=0,ncity=0,done=0,nv; float t; char name[35]; fin=fopen("city.dat","r"); fout=fopen("city.out","w"); while(done==0){nv=fscanf(fin,"%[^;];",name); if(name[1]=='\0')nv=0; if(nv>0) {strcpy(cities[ncity].city,name); fprintf(fout,"\n city %d %s:",ncity+1,cities[ncity].city); for(i=0;i<366;i++) {fscanf(fin,"%f",&t); cities[ncity].temp[i]=t; } ncity++; }
42
ECE 3331else done=1; }
for(i=0;i<ncity;i++) {k=0; for(j=0;j<366;j++) {if(cities[i].temp[j]<=32) k++;} if(k>0) {freeze[nfrz].count=k; strcpy(freeze[nfrz].city,cities[i].city); nfrz++;} } for(i=0;i<nfrz;i++) fprintf(fout,"\n %s %d",freeze[i].city,freeze[i].count); }
43
ECE 3331