AddNumber function in program not working - c

I am having trouble understanding what I should do in the AddNumber function of my program. When the AddNumber function is called in main a pointer variable previous is created, and it takes the user's input and points it at the address of the variable newNum. I created an if statement for it to do that, but I was informed it doesn't do anything.
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
typedef struct A_NewNumber{
struct A_NewNumber *next;
double newNum;
} NewNumber;
NewNumber *AddNumber(NewNumber *previous, char *input){
//char input[16];
//double numEntered = 0;
NewNumber *newNum = malloc(sizeof(NewNumber));
sscanf(input, "%lf", &newNum->newNum);
//sscanf(input, "%s", newNum->enterNumber);
//numEntered = atof(input);
/*if (previous != NULL){
previous->newNum;
}*/
newNum->next = NULL;
newNum->newNum = 0;
return newNum;
}
void PrintList(NewNumber *start){
NewNumber *currentNumber = start;
int count = 0;
while(currentNumber != NULL){
count++;
printf("Numbers:%lf\n",
currentNumber->newNum);
currentNumber = currentNumber->next;
}
printf("Total Numbers Entered%d\n", count);
}
void CleanUp(NewNumber *start){
NewNumber *freeMe = start;
NewNumber *holdMe = NULL;
while(freeMe != NULL){
holdMe = freeMe->next;
free(freeMe);
freeMe = holdMe;
}
}
int main(){
//indexNum = 0;
char command[16];
char input[16];
//float userInput;
NewNumber *userEnter = NULL;
NewNumber *start = NULL;
NewNumber *newest = NULL;
while(fgets(input, sizeof input, stdin)){
printf("Please enter a number->");
printf("Enter 'quit' to stop or 'print' to print/calculate");
sscanf(input, "%s", command);
if(newest == NULL){
start = AddNumber(NULL, input);
newest = start;
}else{
newest = AddNumber(newest, input);
}if(strncmp(command, "print", 5) == 0){
PrintList(start);
}else if(strncmp(command, "quit", 4)== 0){
printf("\n\nQuitting....\n");
break;
//userInput = enterNumber;
}
}
CleanUp(start);
return 0;
}
}

It was not that bad, was just in need of a bit of clean-up.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
// ALL CHECKS OMMITTED!
typedef struct A_NewNumber {
struct A_NewNumber *next;
double newNum;
} NewNumber;
NewNumber *AddNumber(NewNumber * previous, char *input)
{
int res;
// allocate new node
NewNumber *newNum = malloc(sizeof(NewNumber));
if (newNum == NULL) {
fprintf(stderr, "Malloc failed in AddNUmber()\n");
return previous;
}
// convert input string to float
res = sscanf(input, "%lf", &newNum->newNum);
if (res != 1) {
fprintf(stderr, "Something bad happend in AddNUmber()\n");
return previous;
}
// terminate that node
newNum->next = NULL;
// if this is NOT the first node
// put new node to the end of the list
if (previous != NULL) {
previous->next = newNum;
}
// return pointer to new node at end of the list
return newNum;
}
void PrintList(NewNumber * start)
{
NewNumber *currentNumber = start;
int count = 0;
while (currentNumber != NULL) {
count++;
printf("Numbers:%lf\n", currentNumber->newNum);
currentNumber = currentNumber->next;
}
printf("Total Numbers Entered %d\n", count);
}
void CleanUp(NewNumber * start)
{
NewNumber *freeMe = start;
NewNumber *holdMe = NULL;
while (freeMe != NULL) {
holdMe = freeMe->next;
free(freeMe);
freeMe = holdMe;
}
}
int main()
{
char input[16];
NewNumber *start = NULL;
NewNumber *newest = NULL;
int res;
// infinite loop
while (1) {
// give advise
printf("Please enter a number or\n");
printf("'quit' to stop or 'print' to print/calculate\n");
// get input from user
res = scanf("%s", input);
if (res != 1) {
if (res == EOF) {
fprintf(stderr, "Got EOF, bailing out\n");
break;
} else {
fprintf(stderr, "something bad happend, bailing out\n");
break;
}
}
// check if a command was given
if (strncmp(input, "print", 5) == 0) {
PrintList(start);
continue;
} else if (strncmp(input, "quit", 4) == 0) {
printf("\n\nQuitting....\n");
break;
}
// otherwise gather numbers
if (newest == NULL) {
start = AddNumber(NULL, input);
if (start == NULL) {
fprintf(stderr, "AddNumber returned NULL\n");
break;
}
newest = start;
} else {
newest = AddNumber(newest, input);
if (newest == NULL) {
fprintf(stderr, "AddNumber returned NULL\n");
break;
}
}
}
CleanUp(start);
return 0;
}
You should really make a habit of checking all returns and if you don't: be able to give a good reason why you didn't.
Don't forget to switch on all warnings your compiler offers. Even if you don't understand them now, Google might have an answer and if not some people here do (in that order, thank you).

Related

Array of singly linked list won't delete node

I have an array[4] where each index of the array has a singly linked list that holds the following information: name, size. The switch statement controls what index the information will go into according to the size of the party.
Problem: When trying to delete a node according to the size (user inputs) the node will not delete.
I know that all of the cases of deletion have the proper syntax but I cannot figure out why my node will not delete. Appreciate any help.
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct node
{
char name[20];
int size;
struct node *next;
}node;
node* head[4]={NULL,NULL,NULL,NULL};
node* tail[4]={NULL,NULL,NULL,NULL};
//
// proto's
//
void add_party(int, char name[], int size);
void delete_party(char name[], int size);
void list_parties(void);
void change_p_size(char name[], int size);
//
// main function
//
int main()
{
int x;
while (1)
{
fflush(stdin);
printf("\n\nEnter 1 to add a party\nEnter 2 to remove a party\nEnter 3 for the list of the party\nEnter 4 to change party size.\nEnter 5 to quit.\n\n");
// user interface
scanf("%d",&x);
switch(x)
{
char name[20]; //local variables
int size;
case 1:
printf("\nParty Name: ");
scanf("%s", name);
printf("\nParty Size: ");
scanf("%d", &size);
if(size == 0)
{
printf("\nThat is not a valid command. Party not added!\n");
}
if(size >= 1 && size <= 2)
{
add_party(0, name, size);
}
else if(size >= 3 && size <= 4)
{
add_party(1, name, size);
}
else if(size >= 5 && size <= 6)
{
add_party(2, name, size);
}
else if(size >= 7)
{
add_party(3, name, size);
}
break;
case 2:
printf("\nSize of party to delete: ");
scanf("%i", &size);
delete_party(NULL, size);
break;
case 3:
list_parties();
break;
case 4:
change_partysize();
break;
case 5:
exit(0);
default:
continue;
}
}
}
//
//add function
//
void add_party(int h, char *name, int size)
{
//create a new node
int i=0;
int breaker = 0;
node *p;
node *new_item;
new_item = (node *)malloc(sizeof(node)); // allocate memory the size of the struct
strcpy(new_item->name,name);
new_item->size = size;
if(head[h] == NULL && tail[h] == NULL) // if an empty list, create a head and tail
{
head[h] = new_item;
tail[h] = head[h];
new_item->next = NULL;
return;
}
//traversal
for(i=0; i<4; i++)
{
p = head[i];
while(p != NULL)
{
//check that no repeating names. delete nodes that do have repeating names
if(strcmp(p->name,name) == 0)
{
printf("\nSorry, that name is already taken\n");
free(new_item);
return;
}
p = p->next; //go to the next node in the list
}
}
tail[h]->next = new_item;
new_item->next = NULL;
tail[h] = new_item;
}
//
//delete function
//
void delete_party(char *name, int size)
{
int i=0;
int breaker = 0;
node *p;
node *previous;
if(name != NULL)
{
for(i=0; i<4; i++)
{
p = previous = head[i]; //make sure previous trails behind head
while(p != NULL)
{
int c = (strcmp(p->name,name)==0);
if(c==0)
{
breaker = 1;
break;
}
else
previous = p;
p = p -> next;
}
if(breaker==1)
break;
}
}
else
{
int group = -1;
if(size == 1 || size == 2)
{
group = 0;
}
if(size == 3 || size == 4)
{
group = 1;
}
if(size == 5 || size == 6)
{
group = 2;
}
if(size >= 7)
{
group = 3;
}
for(i = group; i > -1; i--)
{
node *p = head[i];
node *previous = head[i];
while(p != NULL)
{
if(p <= size)
{
breaker = 1;
break;
}
else
{
previous = p;
p = p-> next;
}
}
if(breaker)
break;
}
}
if(p == NULL)
return;
if(head[i] == tail[i] && head[i] != NULL) // case 1, empty list
{
printf("\nList is empty!\n");
return;
}
else if(p == tail[i] && p == head[i]) // case 2, one element
{
head[i] = NULL;
tail[i] = NULL;
free(p);
}
else if(p == head[i]) // case 3, delete from the head
{
head[i] = head[i] -> next;
tail[i] = NULL;
free(p);
}
else if(p == tail[i]) // case 4, delete from tail
{
tail[i] = previous;
tail[i] -> next = NULL;
free(p);
}
else // case 5, delete from middle
{
previous -> next = p -> next;
free(p);
}
}
//
// list function
//
void list_parties(void)
{
int i = 0;
node *p=head;
for(i=0; i<4; i++)
{
p=head[i];
while(p != NULL)
{
printf("\n\n%s, %d\n\n", p->name, p->size);
p=p->next;
}
}
}
//
// change function
//
void change_partysize(char *name, int size)
{
int absolute_value = 0;
int comparison = 0;
int current_size = 0;
printf("\nWhat name is your party under?\n");
scanf("%s", name);
//check if the name
printf("\nWhat would you like to change the size to?\n");
scanf("%d", &size);
node *p;
while(p != NULL)
{
if(p->name == name) //new size falls into same range as the size coorelating to the name
{
current_size = p->size;
absolute_value = abs(size - current_size);
comparison = size - current_size;
if(current_size > 7 && size > 7)
{
current_size = size;
return;
}
else if(absolute_value >= 1)
{
//delete the node's value but not the name
delete_party(NULL, size);
//insert node with new name & dif size
add_party(NULL, name, size);
}
else
{
printf("\nYou did not enter a different party size\n");
return;
}
}
}
}
You're declaring new variables p and previous inside the for loop when you delete by size. So when the code after the loop uses these variables, it's using the uninitialized variables declared at the top of the function. Get rid of the declarations and just assign the variables.
Also, if (p <= size) appears to be a typo for if (p->size <= size). I'm surprised you didn't get a compiler warning for that.
You can also replace the if(breaker) check with a test in the for header.
for(i = group; !breaker && i > -1; i--)
{
p = head[i];
previous = head[i];
while(p != NULL)
{
if(p->size <= size)
{
breaker = 1;
break;
}
else
{
previous = p;
p = p-> next;
}
}
}

free() memory using a 'for' loop in a singly linked list

This is my complete program:
#include <stdio.h>
#include <stdlib.h>
#define kArraySize 50
#define kFirstElement 0
struct Name {
char name[kArraySize + 1];
struct Name *nextName;
} *gFirstNameNode, *gLastNameNode;
char GetName(struct Name *currentName);
void AddToList(struct Name *currentName);
void PrintList(struct Name *gFirst);
void FreeTheMemory(struct Name *gFirst);
int main(void) {
struct Name *currentName;
char character;
int counter;
gFirstNameNode = NULL;
gLastNameNode = NULL;
do {
currentName = malloc(sizeof(struct Name));
if (currentName == NULL) {
printf("Out of Memory!\n");
exit(0);
} else {
for (counter = 0; counter <= kArraySize; counter++)
currentName->name[counter] = '\0';
}
character = GetName(currentName);
if ((currentName->name[kFirstElement]) != '\0') {
AddToList(currentName);
}
} while (character != '\r');
PrintList(gFirstNameNode);
printf("Freeing list memory");
FreeTheMemory(gFirstNameNode);
printf("\nFreeing Current Memory!\n");
free(currentName);
printf("Program Ended");
return 0;
}
char GetName(struct Name *currentName) {
char c;
int counter = 0;
printf("Enter a name (hit 'return' to exit):");
for (counter = 0; (counter <= kArraySize) && ((c = getchar()) != '\n'); counter++) {
currentName->name[counter] = c;
}
if (counter == 0) {
return '\r';
} else {
currentName->name[counter + 1] = '\0';
return '\0';
}
}
void AddToList(struct Name *currentName) {
if (gFirstNameNode == NULL) {
gFirstNameNode = currentName;
} else {
gLastNameNode->nextName = currentName;
}
gLastNameNode = currentName;
currentName->nextName = NULL;
}
void PrintList(struct Name *gFirst) {
struct Name *currentPointer;
if (gFirstNameNode == NULL) {
printf("No names in list\n");
printf("----------------\n");
} else {
for (currentPointer = gFirst; currentPointer != NULL; currentPointer = currentPointer->nextName) {
printf("Name: %s\n", currentPointer->name);
}
}
}
void FreeTheMemory(struct Name *gFirst) {
struct Name *currentPointer;
for (currentPointer = gFirst; currentPointer != NULL; currentPointer = currentPointer->nextName) {
free(currentPointer);
printf(".");
}
}
This is where I'm uncertain as to whether what I'm doing is correct. I'm teaching myself C all by myself so please bear with me. What I want to do is delete the node of the linked list from the first node till the last node. For that I created the following function. :
void FreeTheMemory(struct Name *gFirst) {
struct Name *currentPointer;
for (currentPointer = gFirst; currentPointer != NULL; currentPointer = currentPointer->nextName) {
free(currentPointer);
printf(".");
}
}
I'm not sure if by freeing the currentPointer whether I'm actually freeing the linked list. In other words I'm wondering if my logic is correct. I've got no one to ask so I would greatly appreciate some help.
You have a problem doing this:
free(currentPointer);
followed by this:
currentPointer = currentPointer->nextName
You can't deference currentPointer to get the next name after you've freed it.
Instead you should do something like:
currentPointer = gFirst;
while ( currentPointer ) {
struct Name * next = currentPointer->nextName;
free(currentPointer);
currentPointer = next;
}

Get wrong calculation for mean and standard deviation

I'm trying to calculate the mean and standard deviation using following
code segment. I am not getting any compile errors.
When I run it using .txt file, the output
appears following way:
"
"is not a valid integer
with wrong summation, mean and standard deviation and also Can't input double values.
int main ( int argc, char *argv[] )
{
if(buffer == NULL)
{
}
double result = fread(buffer,1,lSize,file);
if(result != lSize){
}
else{
char *str = strtok(buffer," ,");
int count = 0;
while(str != NULL){
double val = (int) strtol(str,&str,10);
if(*str != ' ' && *str != '\0')
{
}
else{
if(count == 0)
{
root = malloc(sizeof(struct node));
root->next = NULL;
root->value = val;
current = root;
count++;
}
else{
double x = createNode(current,val);
}
}
str = strtok(NULL," ,");
}
}
current = root;
printf("Sum is %lf and link count is %lf\n",
getSummation(current), getNodeCount(current));
double mean = getMean(getSummation(current),getNodeCount(current));
double stdev = getStandardDeviation(root, mean,getNodeCount(current));
fclose( file );
free(buffer);
}
}
return 0;
}
int createNode(struct node *n,double val)
{
if(n != NULL){
while(n->next != NULL)
{
n = n->next;
}
n->next = malloc(sizeof(struct node));
n = n -> next;
n -> value = val;
n -> next = NULL;
}
return 1;
}
int getSummation(struct node *element){
double sum = 0.0f;
if(element != NULL)
{
while(element != NULL)
{
sum = sum + element->value;
element= element->next;
}
}
else
{
printf("Null Point Exception thrown");
}
return sum;
}
int getNodeCount(struct node *link)
{
int count = 0;
while(link != NULL)
{
}
return count;
}
double getMean(double summation,int numberOfNodes)
{
}
double getStandardDeviation(struct node *link, double mean,int linkCount)
{
while(link != NULL)
{
}
stdev = sqrt((diffrenceSummation)/(linkCount - 1));
return stdev;
}
1) Add prototypes before main()
//double getSummation(struct node*element);
int getSummation(struct node *element);
int createNode(struct node *n,double val);
int getNodeCount(struct node *link);
#include <math.h>
2) Use consistent format specifiers
//printf("Summation is %lf and link count is %lf\n",
// getSummation(current), getNodeCount(current));
printf("Summation is %d and link count is %d\n",
getSummation(current), getNodeCount(current));
3) Various castings are questionable
// mean = (double)summation/(double)numberOfNodes;
mean = summation/numberOfNodes;
// double linkValue = (double) link->value;
double linkValue = link->value;
// buffer = (char*) malloc(sizeof(char)*lSize);
buffer = malloc(lSize);
// double val = (int) strtol(str,&str,10);
double val = strtol(str,&str,10);

Binary tree not adding strings from file

#include <stdio.h>
#include <stdlib.h>
struct treeNode
{
char *word;
int NumberCnt;
struct treeNode *rightPTR, *leftPTR;
};
typedef struct treeNode node;
node *rootPTR = NULL;
void freeTree(node *currPTR)
{
if (currPTR!= NULL)
{
freeTree(currPTR -> leftPTR);
free(currPTR);
freeTree(currPTR -> rightPTR);
}
}
void printTree(node *currPTR)
{
if (currPTR != NULL)
{
printTree(currPTR ->leftPTR);
printf("%s appeared:%d times\n", currPTR->word, currPTR->NumberCnt);
printTree(currPTR ->rightPTR);
}
}
int insertNode (char* input)
{
node *tempPTR = malloc(sizeof(node));
tempPTR -> word = input;
tempPTR -> NumberCnt=0;
tempPTR -> leftPTR = NULL;
tempPTR -> rightPTR = NULL;
if (rootPTR == NULL)
{
rootPTR = tempPTR;
rootPTR -> NumberCnt++;
}
else
{
node *currPTR = rootPTR;
node *prevPTR = NULL;
while (currPTR != NULL)
{
int comp = strcmp(input, (currPTR->word));
if (comp == 0)
{
printf ("Entry already exists\n");
currPTR->NumberCnt++;
return 1;
}
else if (comp < 0)
{
prevPTR = currPTR;
currPTR = currPTR->leftPTR;
}
else if (comp > 0)
{
prevPTR = currPTR;
currPTR = currPTR->rightPTR;
}
}
int comp = strcmp(input, (prevPTR ->word));
if (comp < 0)
{
prevPTR->leftPTR = tempPTR;
prevPTR ->NumberCnt++;
}
else if (comp > 0)
{
prevPTR->rightPTR = tempPTR;
prevPTR->NumberCnt++;
}
return 0;
}
printf("root1%s\n",rootPTR->word);
return 2;
}
int search(char* input)
{
if (input == rootPTR ->word)
{
printf("Node found %s\n", rootPTR->word);
return 0;
}
else
{
if (input < rootPTR ->word)
{
node *currPTR = rootPTR->leftPTR;
while (currPTR != NULL)
{
if (input == currPTR->word)
{
printf("Node found %s\n", currPTR->word);
return 0;
}
else if (input < currPTR->word)
{
currPTR = (currPTR -> leftPTR);
}
else if (input > currPTR->word)
{
currPTR = (currPTR -> rightPTR);
}
}
printf ("Node not in tree\n");
return 1;
}
if (input > rootPTR ->word)
{
node *currPTR = rootPTR->rightPTR;
while (currPTR != NULL)
{
if (input == currPTR->word)
{
printf ("Node found %s\n", currPTR->word);
return 0;
}
else if (input < currPTR->word)
{
currPTR = (currPTR -> leftPTR);
}
else if (input > currPTR->word)
{
currPTR = (currPTR ->rightPTR);
}
}
printf ("Node not in tree\n");
return 1;
}
}
return 2;
}
void fixWord(char* buff)
{
char* unfixed = buff;
char* fixed = buff;
while (*unfixed)
{
if (isalpha(*unfixed))
{
*fixed=tolower(*unfixed);
*fixed++;
}
*unfixed++;
}
*fixed=0;
}
int main()
{
FILE *ptr_file;
char buff [100];
//ptr_file = fopen ("sherlock.txt", "r");
ptr_file = fopen ("input.txt", "r");
if (!ptr_file)
printf("File read error");
while(fscanf(ptr_file, "%s ", buff ) != EOF)
{
int comparison = strcmp(buff, "endoffile");
if (comparison == 0)
{
return 0;
}
fixWord(buff);
insertNode(buff);
}
fclose(ptr_file);
printf("root:%s\n", rootPTR->word);
return 0;
}
Ok I have this binary tree which is taking string inputs from a file. It works if I pass strings directly to the tree, however when I attempt to pass it the strings I read in form the file it keeps on replacing the root node and does not add them correctly to the tree.
buff is current line value and overwritten on each line reading:
insertNode(buff);
insertNode assigns overwriten buffer.
int insertNode (char* input)
{
node *tempPTR = malloc(sizeof(node));
tempPTR -> word = input;
....
So, you should dynamic allocation for input value as:
int insertNode (char* input)
{
node *tempPTR = malloc(sizeof(node));
tempPTR -> word = strdup(input);
....
You're passing buff to your insert function, and it's storing that in the node. So all your nodes will end up pointing to the same address, that of buff in main.
You need to allocate storage for each string in each node, and copy your input into that. And remember to deallocate properly when you delete your tree.
strdup can be handy for that if your library has it.

Pointers and cstring beginner troubles

I have a problem with the function replace. What I want to accomplish is to replace some special characters, but I haven't written the code yet. So in the replace function we can at this moment just say that the function should print line for line the way I have tried to write. Can someone please correct this function? I can’t really get it
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct list_el {
char *ord;
int num;
struct list_el *prev;
struct list_el *next;
};
typedef struct list_el item;
struct list_el *head, *tail; /*Double linked list that makes it easier to add a element to the end of the FIFO list*/
void addNode(struct list_el *curr);
void readFile();
void print();
void replace();
void random();
void len();
int antE = 0;
int randint(int max)
{
int a = (max*rand()/(RAND_MAX+1.0));
return a;
}
int main(int argc, char *argv[]) {
item *curr;
struct list_el *pa;
if(argc == 3) {
readFile();
}
if(argc == 1) {
printf("Too few arguments, must bee 3");
} else if(strcmp(argv[1], "print") == 0) {
print();
} else if(strcmp(argv[1], "random") == 0) {
random();
} else if(strcmp(argv[1], "replace") == 0) {
replace();
} else if(strcmp(argv[1], "remove") == 0) {
printf("Random kommando kalt");
} else if(strcmp(argv[1], "len") == 0) {
len();
} else {
printf("Not a valid command");
}
if(argc == 3) {
free(curr);
}
}
void addNode(struct list_el *curr) {
if(head == NULL) {
head = curr;
curr->prev = NULL;
} else {
tail->next = curr;
curr->prev = tail;
}
tail = curr;
curr->next = NULL;
}
void readFile()
{
FILE *f = fopen("tresmaa.txt", "r");
if(f == 0) {
printf("Could not open file");
exit(8);
}
item *curr;
if(f != NULL) {
int antE = 0;
head = NULL;
char buffer[300];
while(fgets(buffer, 300-1,f) != NULL) {
curr = (item*)malloc(sizeof(item));
curr->ord = malloc(300);
curr->num = antE;
strcpy(curr->ord, buffer);
antE++;
addNode(curr);
}
}
fclose(f);
}
/*Traverserer listen og printer ut linje for lije
*/
void print()
{
item *curr;
printf("Print text:\n");
for(curr = head; curr != NULL; curr = curr->next) {
printf("%s", curr->ord);
}
}
/*Printer ut en tilfeldig setning
*/
void random()
{
item *curr;
int anum = randint(antE);
for(curr = head; curr != NULL; curr = curr->next) {
if(curr->num == anum) {
printf("Print a random line:\n%s", curr->ord);
}
}
}
void replace()
{
item *curr;
int i;
char tmp[300];
printf("Replace vowels ...\n");
printf("... with vowel 'a'\n");
for(curr = head; curr != NULL; curr = curr->next) {
strcpy(tmp, curr->ord);
for(i = 0; i < strlen(tmp); i++) {
printf("%s", tmp[i]);
}
}
}
void len()
{
item *curr;
long nc;
int i;
nc = 0;
for(curr = head; curr != NULL; curr = curr->next) {
nc += strlen(curr->ord);
}
printf("The text is %d characters long", nc);
}
If you just want to print the lines you can do it without the copying and extra loop:
for(curr = head; curr != NULL; curr = curr->next) {
printf("%s\n", curr->ord);
}
Your current code doesn't work because you tell printf with the %s format that its argument will be a string (aka. a pointer to a zero-terminated sequence of characters), but then you give it a single character, not such a pointer.

Resources