Reputation: 2092
I'm stuck. I created this code in hopes that one function can store data and then another can print it all back to me. The problem is the printing function (aka the itr8 function) gives me some of the values along with segmentation fault.
From this example, I expected the following on screen:
item->outptr=1.00000
item->special=0
item->outptr=2.00000
item->special=1
I don't care at the moment if a dot followed by any number of zeros is appended to the value of outptr. The real result when I try to execute the code is:
item->outptr=2.000000
item->special=1
Segmentation fault
I think I allocated enough memory to store the data but somewhere I think the pointers are messed up. In my itr8 function, I was trying to look for the NULL so that the program can stop after reaching the data set. after all, I allocated memory via calloc which causes each byte of allocated memory to be null to begin with.
What am I doing wrong?
#include <stdio.h>
#include <stdlib.h>
typedef struct{
double outptr;
int special;
}set;
void itr8(set** items){
while (items !='\0'){
printf("item->outptr=%lf\n",(*items)->outptr);
printf("item->special=%d\n",(*items)->special);
items++;
}
}
void ext(set** items,int shapeno){
switch(shapeno){
case 0:
(*items)->outptr=1;
(*items)->special=0;
break;
case 1:
(*items)->outptr=2;
(*items)->special=1;
break;
}
items++;
}
int main(){
const int numitems=100;
set* item=calloc(1,sizeof(set)*numitems); //allocate lots of space
set* ritem=item; //need backup pointer since item is modified in function
ext(&item,0);
ext(&item,1);
item=ritem; //restore pointer for iteration
itr8(&item);
free(ritem);
return 0;
}
Upvotes: 0
Views: 42
Reputation: 75062
while (items !='\0')
in itr8()
us bad because items
won't be NULL
before it goes to invalid area.items++;
in itr8()
will have items
point invalid area because item
, which items
points before the increment, is "array of one element".Try this:
#include <stdio.h>
#include <stdlib.h>
typedef struct{
double outptr;
int special;
}set;
void itr8(set** items){
while ((*items)->outptr!=0.0 || (*items)->special!=0){
printf("item->outptr=%lf\n",(*items)->outptr);
printf("item->special=%d\n",(*items)->special);
(*items)++;
}
}
void ext(set** items,int shapeno){
switch(shapeno){
case 0:
(*items)->outptr=1;
(*items)->special=0;
break;
case 1:
(*items)->outptr=2;
(*items)->special=1;
break;
}
(*items)++;
}
int main(void){
const int numitems=100;
set* item=calloc(1,sizeof(set)*numitems); //allocate lots of space
set* ritem=item; //need backup pointer since item is modified in function
ext(&item,0);
ext(&item,1);
item=ritem; //restore pointer for iteration
itr8(&item);
free(ritem);
return 0;
}
Upvotes: 0
Reputation: 5477
You have two issues.
The first is in your ext
function, where items++
does not modify item
in main()
as you intended. Instead, it should be dereferenced once:
void ext(set** items,int shapeno){
switch(shapeno){
case 0:
(*items)->outptr=1;
(*items)->special=0;
break;
case 1:
(*items)->outptr=2;
(*items)->special=1;
break;
}
++*items;
}
The second is itr8
which doesn't work currently. You don't want to modify items
so you should only pass a set *
and not a set **
. There's also an issue with determining how many items to loop for; the check you have doesn't work because you are comparing against the null character and second because you can not do pointer comparison. One way would be to tell it when to stop iterating by passing a second set *
argument that indicates one past the last element in item
:
void itr8(set* item, set* stop){
while (item != stop){
printf("item->outptr=%lf\n", item->outptr);
printf("item->special=%d\n", item->special);
item++;
}
}
And then you should call it like:
int main(){
const int numitems=100;
set* item=calloc(numitems,sizeof(set)); //allocate lots of space
set* ritem=item; //need backup pointer since item is modified in function
ext(&item,0);
ext(&item,1);
itr8(ritem, item); // note change in how to call it
free(ritem);
return 0;
}
Note that I also changed calloc
slightly; the first argument should be the number of elements and the second should be the size of each element.
Upvotes: 2