signal: segmentation fault (core dumped) error - arrays

Wrote a program that multiply two arrays like this:
uv = u1v1 + u2v2 + u3v3 + ... un*vn
after getting from the user both of the arrays, i get a "signal: segmentation fault (core dumped)" error.
here's the code:
#include <stdio.h>
int scalar_product(int vectorU[], int vectorV[], int vectorLength) {
int i, sum = 0;
for (i = 0; i < vectorLength; i++)
sum += (vectorU[i] * vectorV[i]);
return sum;
}
void userInterface() {
int vectorLength = 0, i;
printf("Please enter the length of the vectors: ");
scanf("%d", &vectorLength);
int vectorU[vectorLength], vectorV[vectorLength];
printf("\nVector U:");
for (i = 0; i < vectorLength; i++) {
printf("\n%d) ", (i + 1));
scanf("%d", &vectorU[i]);
}
printf("\nVector V:");
for (i = 0; i < vectorLength; i++) {
printf("\n%d) ", (i + 1));
scanf("%d", &vectorV[i]);
}
printf(scalar_product(vectorU, vectorV, vectorLength));
}
main(void) {
userInterface();
}

This call of printf is incorrect
printf(scalar_product(vectorU, vectorV, vectorLength));
You need to write at least
printf( "%d\n", scalar_product(vectorU, vectorV, vectorLength));
Also it would be better to declare and define the function like
long long int scalar_product( const int vectorU[], const int vectorV[], int vectorLength) {
long long int sum = 0;
for ( int i = 0; i < vectorLength; i++)
sum += ( long long int )vectorU[i] * vectorV[i];
return sum;
}
To output the result you need to use the format string "%lld\n"..
The type long long int is used to avoid an overflow.
Another way is to declare the function return type as double.
Also you forgot to specify the return type int of the function main.

Here:
printf(scalar_product(vectorU, vectorV, vectorLength));
... you have failed to specify a format for printf. As a result, it attempts to interpret the result of scalar_product() as a pointer to the format string. Undefined behavior results.
If your compiler is not emitting a warning about that then you should either learn how to turn up the warning level so that it does, or else get a better compiler. If your compiler is emitting a warning about it, then take this as a lesson that it is not safe to ignore compiler warnings.
Probably you wanted somethign more like this:
printf("%d\n", scalar_product(vectorU, vectorV, vectorLength));
As a minor additional issue, you have forgotten the return type for main(). Your compiler is probably treating it as returning int, which turns out to be the right thing to do, but that doesn't make your code correct. You want:
int main(void) {
// ...
With those two changes, your program compiles for me without any diagnostics, and runs without error, producing the result I expect.
At least, for small vector lengths. If you try really large vectors then you might exceed the available space for allocating your vectors on the stack.

Related

Segmentation Fault in C when adding an element to array

I am trying to calculate result of the floor function for floats <= 9999.
#include <stdlib.h>
include <stdio.h>
#include "string.h"
int main(int argc, char* argv[]) {
int i, j, k;
int x[1000];
for(i = 0; i < 10000; ++i){
x[i] = i;
}
printf("Enter a float in 0..9999: ");
scanf("%d", k);
tester(x, k);
}
int tester(int* c, int k) {
printf("x[%d] = %d\n", k, c[k]);
}
When compiler came to;
for(i = 0; i < 10000; ++i){
x[i] = i;
}
it gives segmentation fault;
x[i] = i;
here.
I have already checked similar questions about assigning segmentation fault but I couldn't find any solution way. Can anyone help?
The array x is of length 1,000, but you're treating it in the loop as if it's of length 10,000. Accessing x[i] for i greater than or equal to 1,000 is undefined behaviour because the index is out of the array's range.
Thus, a segmentation fault is occurring because your program is accessing memory that it is not allowed to access.
The variable k is initialised and when getting input "&" is missing in the scanf statement. This might have come under segmentation fault since the value "k" is passed in the function tester(). Generally in C lang, we get input with "&", unless if it is a string you don't necessarily mention that in the scanf statement!!.

Converting types resulting in bug

I got stuck in a univ project as follows:
I was doing it before I knew the format of the input, so I started reading it with %s, and it was a char[32].
Then when the project was released, I realized I needed to read the input as int.
So now I started to read it as int and now I don't want to make again all other functions I made, and they are receiving the arguments as an array of chars (char[32]).
So I made a function to convert the int value to int*, because I can't return char[32]. Hence I did, on main, a simple for to pass the values in int* to char[32]. The problem is that, when I print it on main, I see exactly the same values, but when I pass this new char[32] to my functions, I get a bug now. I guess my problem is because of '\0' or something like this.
A simple demonstration is below:
int* convert_dec_to_bin(int n){
printf("\n");
int i, j, k;
int *bits;
bits = (char*)malloc(32*sizeof(int));
for(i = 31, j = 0; i >= 0; --i){
printf("%d", n & 1 << i ? 1 : 0);
if(n & 1 << i){
bits[j] = 1;
}else{
bits[j] = 0;
}
j++;
}
printf("\n");
return bits;
}
int main(){
int i, k, instructionNameInt;
char type;
int *bits;
char bitsC[32];
//char instructionBinary[32]; I was reading like this before, ignore this line
int instructionBinary; //Now I read like this
scanf("%d", &instructionBinary);
bits = convert_dec_to_bin(instructionBinary); //This is a function where I pass the int decimal input to 32 bits in binary as int*.
//Making probably the wrong conversion here, I tried to put '\0' in the end but somehow I failed
for(k = 0; k < 32; k++){
bitsC[k] = bits[k];
}
printf("\n");
type = determine_InstructionType(bitsC);
printf("TYPE: %c\n", type);
instructionNameInt = determine_InstructionName(bitsC, type);
And several other functions...
Can someone light me up how can I fix it? I spent several hours and still didn't achieve to pass this correctly to an array of chars.

Segmentation fault when trying to add elements of an array

I'm trying to create a function that returns as its result the sum of the elements in the array. When I try to run the program, I get a segmentation fault. Could someone please point me in the right direction? Thank you!
int arraySum (int array[], int numberOfElements) {
int result = 0;
for (int i = 0; i < numberOfElements; i++)
{
result += array[i];
}
return result;
}
int main (void) {
int numberOfElements;
int *array = NULL;
printf("How many elements would you like in your array: ");
scanf("%i", &numberOfElements);
printf("\nPlease list the values of the elements in the array: ");
for (int i = 0; i < numberOfElements; i++)
{
scanf("%i", &array[i]);
}
int result = arraySum(array, numberOfElements);
return result;
}
The problem you have is, that in C you need to manually allocate the memory if you are using a pointer instead of say a fixed-size array.
This is usually done by calling malloc, which will return a void-pointer (void*), which you need to cast to the desired type (in your case (int*)) before assigning it.
It is also important to note, that, when using malloc, you need to specify the amount of Bytes you want to allocate. This means that you can't just call it with the number of integers you want to store inside, but rather have to multiply that number with the amount of Bytes that one integer occupies (which depends on the Hardware and Operating System you use, hence you should use sizeof(int) for that purpose, which evaluates to that size at compile time).
I modified your code with a working example of how it could be done:
#include <stdio.h>
#include <stdlib.h>
int arraySum (int array[], int numberOfElements) {
int result = 0;
int i;
for (i = 0; i < numberOfElements; i++) {
result += array[i];
}
return result;
}
int main(int argc, char **argv) {
int numberOfElements;
int *array = NULL;
printf("How many elements would you like in your array: ");
scanf("%i", &numberOfElements);
array = (int*) malloc(numberOfElements * sizeof(int));
printf("\nPlease list the values of the elements in the array: ");
int i;
for (i = 0; i < numberOfElements; i++) {
scanf("%i", &array[i]);
}
int result = arraySum(array, numberOfElements);
printf("\n\nThe result is: %d\n", result);
return 0;
}
You are also trying to return the result in your main function, but the return value of main in C is used to signal whether your program terminated without errors (signalled by a return value of 0) or didn't encounter any issues (any value other than 0).
You need to allocate memory. It is not enough to just declare a pointer. You do it like this: array=malloc(numberOfElements*sizeof(*array));
Also, although it is possible to return result from the main function, you should not do that. The return value from main is usually used for error checking. Change the end of your program to
printf("Sum: %d\n", result);
return 0;
Returning 0 usually means that no error occurred.

Segmentation Fault in C due to pointer

I have recently started coding in C, and am doing some stuff on project Euler. This is my code for challenge three so far. The only problem is when I run the compiled code it throws a segmentation fault. I think it may be due to a pointer I called, the suspect pointer is underneath my comment. I did some research into the subject but I cant seem to be able to fix the error. Any advice?
#include <stdio.h>
#include <stdbool.h>
#include <math.h>
bool is_prime(int k);
int * factors(int num);
int main(){
int input;
while (true){
printf("Enter a number to get the prime factorization of: ");
scanf("%d", &input);
if (is_prime(input) == true){
printf("That number is already prime!");
}else{
break;
}
}
//This is the pointer I think is causing the problem
int * var = factors(input);
int k;
for (k = 0; k < 12; k++){
printf("%d", var[k]);
}
}
bool is_prime(int k){
int i;
double half = ceil(k / 2);
for (i = 2; i <= half; i++){
if (((int)(k) % i) == 0){
return false;
break;
}
}
return true;
}
int * factors(int num){
int xi;
static int array[1000];
int increment = 0;
for (xi = 1;xi < ceil(num / 2); xi++){
if (num % xi == 0){
array[increment] = xi;
increment++;
}
}
}
The factors function has no return statement. It's supposed to return a pointer but it doesn't return anything.
Side note: Enable your compiler's warnings (e.g., with gcc -Wall -Wextra). If they're already enabled don't ignore them!
Your function is declared as
int * factors(int num);
but it's definition doesn't return anything and yet you are using it's return value in assignment. This triggers undefined behavior. It will compile if compiled without rigorous warnings and the return value will most likely be whatever random value happened to be left in the return register (e.g. EAX on x86).
C-99 Standard ยง 6.9.1/12 Function definitions
If the } that terminates a function is reached, and the value of the
function call is used by the caller, the behavior is undefined.

passing array to function in c

can someone please help me figure out what i'm doing wrong here? i'm getting inaccurate results here. I seem to be getting the first value in the array each time and i cant seem to figure out what i'm doing incorrectly
#include <stdio.h>
int getbillsum ( int price[] );
int main( void )
{
int itemprice [10];
int total = 0;
for (int c=0;c <10;c++ ) //Looping to get item prices
{
printf ("\nEnter the price of the item: ");
scanf (" %d", &itemprice[c]);
}
total = getbillsum (itemprice);
printf ("%d", total);
return 0;
}
int getbillsum (int price []) //function to sum the values in array
{
int sum = 0;
for (int i=0; i<sizeof(price); i++)
{
sum+=price[i];
}
return sum;
}
You can't pass arrays to functions in C (well, not as an array anyway). Arrays decay into pointers, the sizeof which is always the same (4 for 32 bit systems, 8 for 64 bits).
For more information see paragraph 2.3 here.
The easiest, most common and most reliable way of solving your issue is to pass the length of the array as a second argument:
int getbillsum (int *price, size_t len)
{
int sum = 0;
for (int i=0; i<len; ++i)
sum += price[i];
return sum;
}
//usage
int main ( void )
{
int price[10];
for(int i=0;i<10;++i)
scanf(" %d", &price[i]);
printf("Sum: %d\n", getbillsum(price, sizeof(price)/sizeof(*price)));
return 0;
}
You also had a problem in your code: you added the return statement inside of your loop.
Just a quick-tip: The sum of an array of ints is not unlikely to be too much for a single int to hold, so I'd change the return-type of getbillsum to long, too
I've also edited your question, addressing quite a lot of issues considering how short your code was:
int getbillsum ( price );//missing type, changed to
int getbillsum ( int price[] );//better would be int getbillsum ( int *price ); but considering your question, left it as array
scanf ("%d", &itemprice[c]);//unsafe, changed it to
scanf (" %d", &itemprice[c]);//add space
total = getbillsum (itemprice,9);//why the second param?
total = getbillsum (itemprice);//to match function prototype
return sum;//moved OUTSIDE of the loop...
sizeof(price) does not give you the length of the array, but the size of the pointer (int price[]), which is probably 4. Also, you immediately return in the first for run. Put return outside the for loop.
You do fix it by supplying the array size, but you never use it. Update your getbillsum function:
int getbillsum (int price [], int length) //function to sum the values in array
{
int sum = 0;
for (int i=0; i<length; i++)
{
sum+=price[i];
}
return sum;
}
In addition to posted answers, you can consider a technique suggested in this answer.
Edit Quoted from comment
it's non-standard, dangerous (think of overflow, forgetting to
dereference at the correct offset and the like), and you should not
try this
In your case it will be something like that :
void *p = calloc(sizeof(itemprice) + sizeof(unsigned long int),1));
*((unsigned long int*)p) = 10;
quote from linked answer
n is now stored at ((unsigned long int)p)
Your getbillsum will look like that now (did not compile it, consider it as pseudocode)
int getbillsum (void* p)
{
int* price = p+sizeof(unsigned long int);
unsigned long int size = *p;
int sum = 0;
for (int i=0; i<size; i++)
{
sum+=price[i];
}
return sum;
}

Resources