So im currently trying to get my program to read a user input ( a double), and store said input in the heap using pointers in C. I allocate 40 bytes to the heap, and the program runs fine up until the program prompts me to enter an input to be stored, At which point after providing the first input, I get the segmentation fault. I know it may come as an out of bounds error, or an error with improper dereferencing, but I can't quite find where I did that. Any help would be greatly appreciated.
Edit: It's become clear my question was a bit confusing, so some clarifications: The goal of the program is to take an unspecified number of grades, starting with an initial heap size 40 bytes (project requirement), and whenever the heap is full, it is copied into a new one of size 80 bytes, with the old 40 bytes being freed. This continues until all grades have been entered.
Placing count as a parameter to defAlloc was a mistake, not quite sure why I put that there to begin with but that his since been removed.
The allocation aspect of this has been fixed and now works properly, im mainly having an issue with accessing elements within the heap and altering them ( grade Scanner Method)
Sorry for the messy code or confusing wordings, im new to both pointer usage and arithmetic as well as posting on stack overflow. Thank you for the responses.
an example of input and output: Input: 81.0 43.0 25.0 73.5
Output: Allocated 40 Bytes to the heap at 0x8d8010 stored 81 in the heap at 0x8d8010
This Repeats for each value until full heap or reaching a sentinel value.
I don't want to give away a whole bunch of information regarding input/output and the project as this is a school assignment (For academic dishonesty purposes) but essentially the issue im having is coming up in the gradeScanner method where im trying to read input and assign it to ptr, ptr+1, etc. Whatever it may be something is causing a segmentation fault
void defAllocator(double **grades);
void gradeScanner(int gradeCount, int allocCount, double *grades, double myGrade);
int main() {
int allocCount;
int gradeCount;
double myGrade;
double *grades;
printf("Enter a list of grades below where each grade is seperated by a newline Character");
printf("After the last grade is entered, enter a negative value to end the list");
defAllocator(&grades);
if(grades == NULL) {
printf("null");
}
else
printf("hello");
gradeScanner(gradeCount, allocCount, grades, myGrade);
}
void defAllocator(double **grades) {
double *arr = (double*)malloc(40);
if(arr != NULL) {
printf("Allocated 40 bytes at the heap at %p\n", grades);
}
else
printf("failed to allocate array");
*grades = arr;
}
void gradeScanner(int gradeCount, int allocCount, double *grades, double myGrade) {
int i =0;
while(i != 5){
if(scanf("%f", myGrade) > 0 && gradeCount == 0) {
*grades = myGrade;
gradeCount++;
printf("%p\n", grades);
printf("%p\n", gradeCount);
i++;
}
else if(scanf("%f", myGrade) < 0) {
i = 5;
}
else if(scanf("%f", myGrade) > 0 && gradeCount > 0) {
*(grades + gradeCount) = myGrade;
}
}
}
Lets get some simple bits going first. The allocation of the grades array
You have
void defAllocator();
then
double myGrade;
double *grades = &myGrade;
defAllocator(grades);
and finally
void defAllocator(double *grades, int count) {
grades = (double*)malloc(40);
printf("Allocated 40 bytes at the heap at %p\n", grades);
}
there is almost nothing correct about any of these lines.
first - what should the allocation function look like. I would make it return the pointer to the allocated memory
double *defAllocator(int count) {
double *arr = (double*)malloc(sizeof(double)*count);
if(arr != NULL)
printf("Allocated 40 bytes at the heap at %p\n", arr);
else
printf("failed to alllocate array");
return arr;
}
Still keeping the hard coded max size. But make it a constant so that you can use it elsewhere, for example to check that not too many results have been entered.
So now we get
const int GRADE_ARRAY_SIZE = 40;
double *defAllocator(int count);
....
double *gradeArray = defAllocate(GRADE_ARRAY_SIZE);
If you want, as an exercise say, to pass the pointer in and have it updated by the allocater, then you need this (its an example of c-style 'pass by reference')
void defAllocator(double **gradeArrayPtr, int count) {
double *arr = (double*)malloc(sizeof(double)*count);
if(arr != NULL)
printf("Allocated 40 bytes at the heap at %p\n", arr);
else
printf("failed to alllocate array");
*gradeArrayPtr = arr;
}
now do
const int GRADE_ARRAY_SIZE = 40;
void defAllocator(double **gradeArrayPtr, int count);
....
double *gradeArray = NULL;
defAllocate(&gradeArray, GRADE_ARRAY_SIZE);
others have pointed out errors in the scanner code, but without the allocater working nothing else will work either
OK now the allocator is fixed lets look at the scanner code. We have
int allocCount;
int gradeCount;
double myGrade;
double *grades;
gradeScanner(gradeCount, allocCount, grades, myGrade);
and the actual function.
void gradeScanner(int gradeCount, int allocCount, double *grades, double myGrade) {
int i =0;
while(i != 5){
if(scanf("%f", myGrade) > 0 && gradeCount == 0) {
*grades = myGrade;
gradeCount++;
printf("%p\n", grades);
printf("%p\n", gradeCount);
i++;
}
else if(scanf("%f", myGrade) < 0) {
i = 5;
}
else if(scanf("%f", myGrade) > 0 && gradeCount > 0) {
*(grades + gradeCount) = myGrade;
}
}
}
Note, you code invokes multiple lots of Undefined Behavior so its hard to know exactly what is happening, I am guessing, But in fact tryi\ing to reason about UB is a big mistake.
Lets look at this piece
if(scanf("%f", myGrade) > 0 && gradeCount == 0)
OK so thats always false (gradeCount != 0) so we move onto the next
else if(scanf("%f", myGrade) < 0) {
i = 5;
}
Anyway this is false because of the test for < 0 that only happens at EOF
So now we get to
else if(scanf("%f", myGrade) > 0 && gradeCount > 0) {
*(grades + gradeCount) = myGrade;
}
this reads the next value from the input, did you mean that?
same errror with 'myGrade' instead of '&myGrade' (very bad UB)
but scanf might return 1 and gradeCount is almost certainly > 0 (50/50 chance given that its unitialized).If this did test to true we do
*(grades + gradeCount) = myGrade;
more normally this is written
grades[gradeCount] = myGrade;
well gradeCount is uninitialized so this is very bad UB. Note that if this had worked myGrade will be unitialized too (also UB)
So
Plus
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.