why does the printf not showing - c

I need help. It doesnt display the printf in the mean function. I am doing a dynamic allocation in c and the add function works but the mean function does not display. There is no problem to the add function it works but the max does not. I am sorry I know this problem is simple but still cant get the answer. I am also getting a warning to the add function during the call in main.
This is my code:
typedef int* Statistician;
void add(Statistician answer, int *count, int *SIZE, int item);
|
[Note] expected 'Statistician' {aka 'int *'} but argument is of type 'int **'
int main() {
int SIZE;
Statistician *answer;
int count;
int item;
add(answer, count, SIZE, item);
|
//[Warning] passing argument 1 of 'add' from incompatible pointer type [-Wincompatible-pointer-types]
printf("\nThe mean is: %.2f", mean(answer, SIZE));
return 0;
}
This is the add function:
void add(Statistician answer, int *count, int *SIZE, int item) {
int i;
printf("Enter n: ");
scanf("%d", &item);
answer = (int*)malloc(item * sizeof(int));
if(item == NULL) {
printf("Memory not allocated.\n");
exit(0);
}
else {
for(i = 0; i < item; ++i) {
scanf("%d", &answer[i]);
}
printf("Elements of array are: ");
for(i = 0; i < item; i++) {
printf("%d ", answer[i]);
}
if(item == 10) {
int m;
printf("\nAppend array: ");
scanf("%d", &m);
answer = realloc(answer, m * sizeof(int));
for(i = item; i < item + m; i++) {
scanf("%d", &answer[i]);
}
item = item + m;
int temp, j;
for(i = 0; i < item; i++) {
for(j = 0; j <= i; j++) {
if(*(answer + i) < *(answer + j)) {
temp = *(answer + i);
*(answer + i) = *(answer + j);
*(answer + j) = temp;
}
}
}
printf("Final array: \n");
for(i = 0; i < item; ++i) {
printf("%d ", answer[i]);
}
}
}
}
This is the max function that doesnt display:
float mean(Statistician answer, int count) {
int mean =0;
int cnt = 0;
for(int i=0;i<count;i++){
mean = mean + answer[i];
cnt++;
}
mean = mean / cnt;
return mean;
}

I fully expected to find a duplicate but I didn't.
The first argument to add is declared to be int ** (via typedef) and you passed it a paramter of type int *. The compiler will let you do this with a warning, but it's almost always wrong. Don't do it.
If you're running 64 bit code, anything can happen after you stomp memory. 32 bit code is slightly more predictable but it's still going to end badly.
From your code, it looks like you want void add(Statistician *answer, Statistician answer; and add(&answer.
The deep learning of pointers is here. The thing you need to modify in the calling function is the thing whose address is passed to the called function. Allocating arrays with malloc almost always ends up being double pointers.

Related

Why do i get segmentation fault 11?

Why do I get segmentation fault 11? I get it quite often, and I know this time it is about the function. If anyone can help, please do, the code is down below! I am trying to make a program, that WITH A FUNCTION, can rearrange an array in ascending order and then print it in main in reverse order.
#include "stdio.h"
void changxr(int *counter, int *arrsize, int *j, int *arr[]);
int main()
{
int a, i, j, counter;
int arrsize;
int arr[100];
printf("pick an arraysize: \n");
scanf("%d", &arrsize);
printf("type %d numbers \n", arrsize);
for (counter = 0; counter < arrsize; counter++)
{
scanf("%d", &arr[counter]);
}
for (int c = arrsize - 1; c >= 0; c--)
{
printf("%d ", arr[c]);
}
changxr(&counter, &arrsize, &j, &arr[&counter]);
for (counter = arrsize - 1; counter >= 0; counter--)
{
printf("%d ", arr[counter]);
}
}
void changxr(int *counter, int *arrsize, int *j, int *arr[])
{
int a;
for (*counter = 0; *counter < *arrsize; *counter++)
{
for (*j = *counter + 1; *j < *arrsize; *j++)
{
if (*arr[*counter] > *arr[*j])
{
a = *arr[*counter];
*arr[*counter] = *arr[*j];
*arr[*j] = a;
}
}
}
}
New code:
#include "stdio.h"
void changxr(int arrsize, int *arr[]);
int main()
{
int a, i, j, counter;
int arrsize;
int arr[100];
printf("pick an arraysize: \n");
scanf("%d", &arrsize);
printf("type %d numbers \n", arrsize);
for (counter = 0; counter < arrsize; counter++)
{
scanf("%d", &arr[counter]);
}
for (int c = arrsize - 1; c >= 0; c--)
{
printf("%d ", arr[c]);
}
changxr(arrsize, &arr[counter]);
for (counter = arrsize - 1; counter >= 0; counter--)
{
printf("%d ", arr[counter]);
}
}
void changxr(int arrsize, int *arr[])
{
int a, counter, j;
for (counter = 0; counter < arrsize; counter++)
{
for (j = counter + 1; j < arrsize; j++)
{
if (*arr[counter] > *arr[j])
{
a = *arr[counter];
*arr[counter] = *arr[j];
*arr[j] = a;
}
}
}
}
This is what I got from debugging:
"Program received signal SIGSEGV, Segmentation fault.
0x0000555555555355 in changxr (arrsize=3, arr=0x0) at main.c:33
33 for(j=counter+1; j<arrsize; j++) { if(*arr[counter]>*arr[j]){
(gdb) continue"
You do not need two levels of indirection (int *arr[], *arr[counter], *arr[j]). When arr is passed to a function, it will decay to a pointer-to-its-first-element, or more simply, an int *.
&arr[counter] is also an int *, but it is the address of the array element one past the elements you've initialized. This would start your sorting function in the incorrect place.
Your program segfaults because it attempts to use this value as an int ** (int *[]).
gcc -Wall highlights this clearly:
prog.c: In function ‘main’:
prog.c:24:22: warning: passing argument 2 of ‘changxr’ from incompatible pointer type [-Wincompatible-pointer-types]
24 | changxr(arrsize, &arr[counter]);
| ^~~~~~~~~~~~~
| |
| int *
prog.c:3:32: note: expected ‘int **’ but argument is of type ‘int *’
3 | void changxr(int arrsize, int *arr[]);
| ~~~~~^~~~~
Things to do:
Simply pass the array and the length of the array to your function.
Use a single level of indirection in your function definition, and when accessing the array.
Use a variable-length array.
Use an auxiliary function for printing.
Declare variables when you need them, in the correct scope.
You should also consider checking the return value of scanf is the expected number of successful conversions.
The refactored code:
#include <stdio.h>
void changxr(int *a, size_t length)
{
for (size_t i = 0; i < length; i++) {
for (size_t j = i + 1; j < length; j++) {
if (a[i] > a[j]) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
}
void print_reverse(int *a, size_t length)
{
printf("[ ");
while (length--)
printf("%d ", a[length]);
printf("]\n");
}
int main(void)
{
size_t size;
printf("Pick an array length: ");
if (1 != scanf("%zu", &size) || size == 0) {
fprintf(stderr, "Invalid length input.\n");
return 1;
}
int array[size];
printf("Enter %zu numbers:\n", size);
for (size_t i = 0; i < size; i++) {
if (1 != scanf("%d", array + i)) {
fprintf(stderr, "Invalid integer input.\n");
return 1;
}
}
printf("Array (in reverse): ");
print_reverse(array, size);
changxr(array, size);
printf("Array, Sorted (in reverse): ");
print_reverse(array, size);
}

passing argument 1 of 'better' makes pointer from integer without a cast

Here's a fairly simple program that finds the max element of an 2d array grades and prints it out to the screen
#include <stdio.h>
const int t = 5;
int num_of_students;
int better(int grades[num_of_students][t], int num_of_students)
{
int i, k;
int max = grades[0][0];
for (i = 0; i < num_of_students; i++)
{
for (k = 0; k < t; k ++)
{
if (grades[i][k] > max)
{
max = grades[i][k];
}
}
}
return max;
}
int main(void)
{
int i, k;
printf("Give the number of students who took the test: ");
scanf("%i", &num_of_students);
int grades[num_of_students][t];
for (i = 0; i < num_of_students; i++)
{
printf("Student %i\n", i+1);
for (k = 0; k < t; k++)
{
printf("Give the score on test %i: ", k+1);
scanf("%i", &grades[i][k]);
while (grades[i][k] < 0 || grades[i][k] > 100)
{
printf("Not an acceptable score, try again %i: ", k+1);
scanf("%i", &grades[i][k]);
}
}
}
int max = better(grades[num_of_students][t], num_of_students);
printf("The best score is %i\n", max);
}
Yet when I'm trying to run the program the following errors pop up:
test.c:47:45: warning: passing argument 1 of 'better' makes pointer from integer without a cast [-Wint-conversion]
test.c:6:16: note: expected 'int (*)[(sizetype)t]' but argument is of type 'int'
For starters change the function declaration from
int better(int grades[num_of_students][t], int num_of_students)
to
int better(int num_of_students, int grades[num_of_students][t] )
Otherwise it is unclear whether in the declaration of the first parameter int grades[num_of_students][t] there is used the global variable num_of_students or the identifier of the second parameter. That is the function declaration as is will confuse readers of the code.
And call it like
int max = better( num_of_students, grades );
Otherwise you are trying to pass the non-existent element of the array grades[num_of_students][t] of the type int instead of the array itself.

Stack smashing error when manipulating array of ints in function

So I'm trying to make a simple program that takes an array that is partially full and adds an integer to the beginning shifting all existing elements to the right. It seems what I have here adds and shifts things properly but once all the code executes, I get a stack smashing detected error.
Here is my code:
#include <stdio.h>
void addCommand(int *, int, int);
void main() {
int i;
int list[10];
list[0] = 1;
list[1] = 5;
printf("Before add:\n");
for (i = 0; i < 2; i++) {
printf("%d\n", list[i]);
}
addCommand(list, sizeof(list), 4);
printf("Adding 4:\n");
for (i = 0; i < 3; i++) {
printf("%d\n", list[i]);
}
}
void addCommand(int *arr, int size, int new) {
int k;
printf("%d", arr[0]);
for (k = size - 1; k >= 0; k--) {
if (&arr[k] != NULL) {
if (k > 0) {
arr[k] = arr[k-1];
} else {
arr[k] = new;
}
}
}
}
And here's the output:
If anyone could point out what I'm doing wrong here, it would be much appreciated!
addCommand(list, sizeof(list), 4);
above line doesn't pass number of element in list array. you have to do something like this:
sizeof(arr)/sizeof(arr[0])

Warning messages for all of my functions using pointers. Expected 'int*' but argument is of type 'int (*)[10]'

The code works fine I'm just worried about the warning messages I'm getting, would there be a way to make them not appear? Is there any reason to be worried about them? Also farther down in the code I don't quite understand what I did or why it worked. It wasn't working before so I looked up what other people did with pointers and it works now
Warning passing argument 1 of 'readarray' from incompatible pointer type [-wincomp
readarray(&a);
^
note: expected 'int*' but argument is of type 'int(*)[10]'
void readarray (int*);
^
This is the warning message, I get it for each of my functions^^^^^^^^^^^^^^^^^^
I understand why it's having issues, I think, but I don't understand how I could change anything
#include <stdio.h>
#define n 10
void readarray (int*);
int findmaxvalue(int*);
void reversearray(int*, int*);
void printarray(int*);
int main(void)
{
int a[n], i, b[n];
for (i = 0; i < n; i++)
{
a[i] = 0;
}
for (i = 0; i < n; i++)
{
b[i] = 0;
}
readarray(&a);
findmaxvalue(&a);
reversearray(&a, &b);
printarray(&b);
return 0;
}
void readarray (int *a)
{
int *q;
q = a;
printf("Enter up to 10 numbers. Terminate by entering a 0\n");
Right here, why can't I use 'a' instead of 'a+n'
for(q = a; q < a+n; q++)
{
scanf("%d", q);
if (*q == 0)
break;
}
printf("\n");
}
int findmaxvalue(int *a)
{
int i, max;
max = a[0];
for (i = 1; i < n; i++)
{
if (a[i] > max)
max = a[i];
}
printf("The highest element in the array is: %d\n\n", max);
return max;
}
void reversearray(int *a, int *b)
{
int *i, *j, t;
for (i = a; i < a+n; i++)
{
for (j = i + 1; j < a+n; j++)
{
if (*j < *i)
{
t = *j;
*j = *i;
*i = t;
}
}
}
for (i = a + n - 1, j = b; i > a; i--, j++)
{
*j = *i;
}
}
void printarray(int *b)
{
int *q;
q = b;
printf("The reversed array in descending order is:\n");
for (q = b; q < b+n; q++)
{
printf("%d ", *q);
}
}
I think the error message is pretty self-describing.
In your code, a is an array type, having int [10]. You pass &a, which is of type pointer to an array of 10 ints, or, int (*)[10] which is not the same type as a pointer to int, i.e., int *. Hence the compiler screams.
As array type variables decay to the pointer to the first element of the array while passed as function arguments, you should call your function like
readarray(a);

Access violation reading location 0xFFFFFFFE

void inputArray(int* *pa, int *n)
{
do {
printf("Input the elements: ");
scanf_s("%d", n);
if (*n < 0)
{
printf("Error! Input again\n");
}
} while (*n < 0);
*pa = (int*)malloc(*n * sizeof(int));
for (int i = 0; i < *n; i++)
{
printf("Elements a[%d]: ", i);
scanf_s("%d", pa + i);
}
}
void outputArray(int* *pa, int n)
{
printf("\nContent of the array\n");
for (int i = 0; i < n; i++)
{
printf("a[%d] = %d\n", i, *(pa + i));
}
}
int main()
{
int *A;
int n;
inputArray(&A, &n);
outputArray(&A, n);
free(A);
_getch();
return 0;
}
When the program display the array, I got the error "Exception thrown at 0x00AD372D (ucrtbased.dll)"
I'd tried many times to fix the error, but it still displays the error when the program displays the output of array, please give me some advice. Thanks for reading.
A debugger will have shown you where the problems are.
You pass the address of a pointer to inputArray and get it as an int **: fine
You allocate the array with *pa = (int*)malloc(*n * sizeof(int)); : almost fine. All indirections levels are correct, but you should not cast malloc in C (should be: *pa = malloc(*n * sizeof(int));)
But scanf_s("%d", pa + i); is plain wrong. pa is a pointer that contains the address of the allocated array, so the array is at *pa not at pa. You should write scanf_s("%d", *pa + i);
For outputArray, you have no reason to pass a pointer to the array. But if you do, the values will be at (*pa)[i], not at *(pa + i) which is the same as pa[i], so you should use : printf("a[%d] = %d\n", i, (*pa)[i]);.
But the correct way would be:
void outputArray(int *pa, int n)
{
printf("\nContent of the array\n");
for (int i = 0; i < n; i++)
{
printf("a[%d] = %d\n", i, pa[i]);
}
}
...
outputArray(A, n);
You have a double pointer int* *pa in you function inputArray, of wich you allocated space for *pa. and you are reading value to pa. First you should allocate memory for pa then read value to it.
for (int i = 0; i < *n; i++)
{
pa[i] = malloc(sizeof(int));
printf("Elements a[%d]: ", i);
scanf_s("%d", pa[i]);
}

Resources