inner product function in C [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I try to write a fuction for inner product without using array subscripting. I have been looking the code for hours.
Still I could not fix mistake. Can someone fix it?
#include<stdio.h>
#include<stdlib.h>
int inner_product(int *a, int *b, int size)
{
int sum = 0, i;
for (i = 0; i < size; ++i)
{
printf("enter value for first array: ");
scanf("%d", &(a + i));
}
for (i = 0; i < size; ++i)
{
printf("enter value for first array: ");
scanf("%d", &(b + i));
}
for (i = 0; i < size; ++i)
sum += *(a + i) * *(b + i);
return sum;
}
int main()
{
int n, a, b;
printf("How many elements do you want to store? ");
scanf("%d", &n);
printf("%d", inner_product(&a, &b, n));
system("pause");
return 0;
}

You have so many errors in your code. First, you are not defining your arrays as arrays, but as single int values. You should define them correctly:
int *a, *b;
Second, you are not allocating your arrays. If you want to create them on runtime you will have to use malloc() after you get the size for them:
a = (int*)malloc(sizeof(int) * n);
b = (int*)malloc(sizeof(int) * n);
Third, it is not necessary to pass your array values as reference, because you will not need to modify them:
printf("%d", inner_product(a, b, n));
Inside your inner_product() function:
&(a + i) and &(b + i) won't give you the memory position of the array item (because it depends on the memory block size). You should use &a[i] and &b[i] instead to get the array values.
Because your variables a and b are arrays, your inner product should be calculated this way:
for (i = 0; i < size; ++i)
sum += a[i] * b[i];
Tip: be sure to freeing your allocated a and b arrays by calling free(a) and free(b) after calling inner_product().
That's it!

a and b must be arrays with memory allocated to them.
int a[1000];
int b[1000];
is a quick fix, but best if the code checks that inputs are no larger than 1000 (if this is only a class assignment, you can get away without such checks, but production code needs to be more robust). You would not need & before a and b when calling the function, i.e. instead call inner_product(a, b, n).

Related

Segmentation fault in passing multidimensional arrays to functions in C

We saw passing arrays to functions using pointers in my intro. to C class, and I'm trying to learn how to pass multidimensional arrays on my own. I tried writing a function to assign the values of the entries of a matrix onto a local array, but I get a segmentation fault. I was hoping someone could explain why this happens and how to fix it. I'm using the terminal on macOS Sierra. Thanks in advance. My code is below:
#include <stdio.h>
#include <stdlib.h>
void fillMatrix();
int main(void){
int rows, cols;
printf("\nEnter the number of columns:\n");
scanf("%d", &cols);
printf("\nEnter the number of rows:\n");
scanf("%d", &rows);
int matrix[rows][cols];
fillMatrix(&matrix[rows][cols], rows, cols);
for (int i = 0; i < rows; ++i){
for (int j = 0; j < (cols - 1); ++j){
printf("%d ", matrix[i][j]);
} printf("%d\n", matrix[i][(cols -1)]);
}
return 0;
}
void fillMatrix( int *matrix, int rows, int cols ){
for (int i = 0; i < rows; ++i){
for (int j = 0; j < cols; ++j){
printf("\nPlease enter the A(%d,%d) entry:\n", i, j);
scanf("%d", &*(matrix + (i*cols) + j));
}
}
return;
}
Given the declaration
int matrix[rows][cols];
This code is wrong:
fillMatrix(&matrix[rows][cols], rows, cols);
The address of &matrix[rows][cols] is past the end of the matrix.
The first element of the matrix is &matrix[0][0], and the last element of the matrix is &matrix[rows-1][cols-1].
Also, this declaration
void fillMatrix();
will cause problems with this defintion:
void fillMatrix( int *matrix, int rows, int cols ){
...
They need to match. Right now, because of the void fillMatrix() declaration up top, arguments get passed to the function via default argument promotion, but because the definition has explicit arguments, the function itself expects the arguments to be passed as int * or int. You're probably not having problems with that as the defaults for those arguments are likely the same as those arguments, but function definitions and declarations generally must match exactly.
I haven't examined your code for other issues.
In C when you are declaring an array you need to specify its size at the time of compilation. When you decelerate the array in line
int matrix[rows][cols];
You actually initialise its size with rubbish values. In case of my compiler it was initialised with size of [0][0]. In order to achieve what you want you need to do one of two things:
Specify explicitly what is the size of the array before compilation
Dynamically allocate space for the array

The purpose of a triple pointer in C [duplicate]

This question already has answers here:
Triple pointers in C: is it a matter of style?
(5 answers)
Closed 4 years ago.
While I have seen some threads on this, I fail to understand the meaning behind triple pointers, since it seems that it's possible to do the same without them.
void Reading(int *N, int ***M) {
printf("Input an integer N: \n");
scanf("%d", N);
*M = malloc(N * sizeof(int*));
int i;
for (i = 0; i < N; i++)
*(*M+i) = malloc(N * sizeof(int));
printf("Input N*N integers that will form a matrix \n");
int i, j;
for (i = 0; i < *N; i++)
for (j = 0; j < *N; j++)
scanf("%d", &((*M)[i][j]));
}
This code makes **M a 2D array. If I take the malloc procedures and put them into main, the triple pointer isn't needed anymore. Could someone please explain why this is the case ?
If I take the malloc procedures and put them into main, the triple pointer isn't needed anymore.
There are two ways to pass a variable to a function: either by value or by reference. When you pass the reference of a variable, that allows you to modify it.
Example:
void fun(int a) {
a = 42; // Does nothing
}
int b = 9;
fun(b);
// b is unchanged.
void fun(int *a) {
*a = 42;
}
int b = 9;
fun(&b);
// b equals 42.
Your variable happens to be a of type int **, when you pass the address (reference) of this variable, this makes it a int ***.

Problems with C language code [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Write a complete program.
The program should read two integers: m and n, from the keyboard.
Allocate memory for a dynamic 2D m * n array of doubles.
Initialize the array according to the formula A[i][j]=(i-5)/(j+1).
My code:
#include <stdio.h>
#include <math.h>
int main() {
int m,n;
scanf ("%d %d",&m &n);
double**A=(double**) malloc (m*size of (double*));
double*B=(double*) malloc (m*n * size of (double));
for (int i=0;i<n;i++){
A[i]=B+i*m;
}
for (int i=0;i<n;i++){
for (int j=0;i<m;j++){
A[i][j]=(i-5)/(j+1);
}
}
free (A);
free (B);
return 0;
}
Few things wrong:
size not defined.
#include <math.h> is not needed since you don't call any math functions.
Strictly speaking you should #include <stdlib.h> as this declares malloc() and friends.
A , is missing in scanf ("%d %d",&m &n);.
No need to cast malloc() return value.
Always start variable names with a small letter.
You have one } too many.
Indentation and code formatting is really bad and is asking for trouble.**
...
Check this section of the C-FAQ to see if you've done the allocation correctly.
Idea: Read through the C-FAQ mentioned above, it will teach you a lot and will turn out to be a valuable time investment.
**Here's an example of good code indentation & formatting (without fixes):
int main()
{
int m;
int n;
scanf("%d %d", &m, &n);
double** A = malloc(m * size of (double*));
double* B = malloc(m * n * size of (double));
for (int i = 0; i < n; i++)
{
B[i] = B + i * m;
}
for (int i = 0; i < n; i++)
{
for (int j = 0; i < m; j++)
{
A[i][j] = (i - 5) / (j + 1);
}
}
free(A);
free(B);
return 0;
}
Well, I fixed the superfluous }.

How to use pointers in C/ returning an int array?

I'm currently trying to write the code for a simple Quicksort in C, but I can't seem to understand C syntax and pointers. I'm used to coding in Java, so I'm a little confused on how to return int arrays, and what I'm doing wrong.
Here is my code right now, any help would be greatly appreciated.
#include <stdio.h>
#define MAX 100
int input[MAX];
int* QuickSort(int A[], int n);
int* combine (int first[], int pivot, int last[]);
//main method to run program
int main()
{
int i, n;
//read in input and store values in array named input
printf ("Enter several numbers separated by spaces or returnsand ended by Ctrl-D:\n");
for (n = 0; n < MAX && scanf("%d", &input[n]) != EOF; n++);
//runs QuickSort on the array
int new[n] = QuickSort(input, n);
printf("Here is your sorted array:\n");
//goes through sorted array to print values
for (i = 0; i < n; i++)
printf("%d\n", new[i]);
}
int* QuickSort(int A[], int n)
{
//if array has 1 value or is empty, automatically return
if (n <= 1)
return A;
int pivot = A[0];
int less[n/2];
int more[n/2];
int lesscount = 0;
int morecount = 0;
int i;
for (i = 1; i<n; i++)
{
if (A[i] <= pivot)
{
less[lesscount] = A[i];
lesscount++;
}
else if (A[i] > pivot)
{
more[morecount] = A[i];
morecount++;
}
}
int size = n/2;
return combine(QuickSort(less, size), pivot, QuickSort(more, size));
}
int* combine (int first[], int pivot, int last[])
{
int firstsize = sizeof(first)/sizeof(first[0]);
int lastsize = sizeof(last)/sizeof(last[0]);
int totalsize = firstsize + lastsize + 1;
int combined[totalsize];
int n;
for (n =0; n<firstsize; n++)
{
combined[n]= first[n];
}
combined[n]=pivot;
n++;
int m;
for (m =0; m<totalsize; m++)
{
combined[n] = last[m];
n++;
}
return combined;
}
The basics
A pointer is a memory address which you can dereference and access. It's very different from an object and is (mostly likely) just an 8-byte value. Whereas in Java you might be able to pass around objects (which do point to some memory somewhere), in C you must be a lot more careful about what memory you're pointing.
In particular, there is a difference between the stack and the heap. The stack is what your program uses to track local variables and will automatically allocate space. On the other hand, the heap is usually something you need to manage yourself. In particular, you won't get heap addresses unless you explicitly allocate it (i.e., with malloc). Why the distinction? Because the stack automatically allocates space, but also automatically deallocates space on function return.
Why does this apply to you?
Let's take a look on some of your functions:
int* combine (int first[], int pivot, int last[])
/* i.e., int* combine (int *first, int pivot, int *last) */
{
int firstsize = sizeof(first)/sizeof(first[0]);
int lastsize = sizeof(last)/sizeof(last[0]);
int totalsize = firstsize + lastsize + 1;
int combined[totalsize];
/* The rest of the code */
return combined;
}
You're returning combined, a stack allocated variable to whoever is calling your function. While doing this is "legal" in the strict sense, it's not correct because once you've returned from the function, the program will automatically deallocate the memory. This means you're probably getting some very confusing results and/or faults.
Now, how do you fix this?
In your case, quicksort doesn't need more space, just some clever manipulation of variables. Thus, you actually don't even need to use any of the sub arrays, nor do you need to return any arrays. The neat thing about pointers is that you get an address to memory. Thus, if you change that is pointed to (i.e., A[0] = x), then any other function which also knows about A will see that update.
And applied to quicksort?
Your initial implementation isn't quite correct either. Quicksort can be roughly broken down into two steps: partition and combine. When you partition, you want to separate all values less than a pivot value from all values greater than a pivot value. However, because you don't already know how many that is, assuming you'll have size/2 in each partition is going to cause you trouble.
For partition, you can use an in place iterative method. Something like this:
while index < end:
if A[index] < pivot:
index ++
else if A[index] > pivot:
swap(A[index], A[end])
end --
swap(pivot, A[index])
(There may be some off by one errors in the above.) The basic idea is that by keeping track of both a lower part and an upper part with two indices, you "add" the current value you're comparing against to the proper side (by moving to the next index, or swapping and decrementing the end). And by doing this in place, you don't need to deal with memory allocation.
The recursive step then becomes knowing where your sub-pieces are and recursively calling sort of each.

C programming confused with output [duplicate]

This question already has answers here:
Weird behavior when printing array in C?
(5 answers)
Closed 9 years ago.
Can anyone please explain the output for the following program? I get an infinite loop if used a[i] = 0; and a segfault when I used a[i] = i; and also the i ranges between 0 - 9 when used a[i] = 0; whereas it goes to 39 when used a[i] = i; before giving a segfault.
#include<stdio.h>
#include<stdlib.h>
int mult(int a, int b);
int main()
{
int a[10];
int i = 0;
for(i=0; i < sizeof(a); i++)
{
a[i] = i;
printf("a[i]=%d i=%d\n", a[i], i);
}
return 0;
}
When you apply the sizeof operator to an array type, the result is the total number of bytes in the array, i.e, sizeof(a) determines the number of bytes in a which is not the number of elements in the array in this case. Use sizeof(a)/sizeof(a[0]) to get number of elements in the array a.
Replace
for(i=0;i<sizeof(a);i++)
with
for(i=0;i<sizeof(a)/sizeof(a[0]);i++)
Also, no need to initialize i twice.
You probably want to change this line:
for(i=0;i<sizeof(a);i++)
to this:
for(i=0;i<sizeof(a)/sizeof(a[0]);i++)
Note:
sizeof(a) gives the number of bytes in a[].
sizeof(a)/sizeof(a[0]) gives the number of elements in a[].
sizeof doesn't do what you think it does. It's returning the number of bytes occupied by the entire array.
You want the numeric length of the array, not the byte size.
Try something like this:
const int array_size = 10;
int a[array_size];
for (int i = 0; i < array_size; i++) {
a[i] = i;
printf("a[%d] = %d\n", i, a[i])
}
If you want to know how far to loop, without storing it in a separate const, use sizeof(a)/sizeof(a[0])

Resources