Hackerrank circular array rotation segmentation faults - c

My following code sucessfully runs in sample input but gives segmentation faults in 13 test cases.
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
int main(){
int n;
int k;
int q;
int index[q];
scanf("%d %d %d",&n,&k,&q);
int *a = (malloc(sizeof(int) * n));
for(int a_i = 0; a_i < n; a_i++){
scanf("%d",&a[a_i]);
}
for(int a0 = 0; a0 < q; a0++){
int m;
scanf("%d",&m);
index[a0] = m;
}
for(int i=0; i<k; i++){
int ap = a[n-2];
for(int p=1; p<n-1; p++){
a[p] = a[p-1];
}
a[0] = a[n-1];
a[n-1] = ap;
}
for(int j=0; j<q;j++){
printf("%d\n", a[index[j]]);
}
return 0;
}
I am unable to find where the segmentation fault is. Also check out this:where I asked about declaring a as a pointer using malloc
There might have been chances that using malloc() to declare a would have lead to segmentation faults since it does not check for allocation error, but even when i defined a as an array the problem still remained.

q is not initialized, but is used as the argument to the declaration of an array.
You should use malloc to allocate the index array, after reading the value of q.

Related

Determinant of a Matrix in C, Troubleshooting

main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "matrix.h"
int main(){
//Prompt the user for the size of matrix to be calculated.
printf("Welcome to the matrix determinant calculator!\n\n");
printf("Please select the matrix size you would like to input: \n");
printf("\t (A): 2x2 matrix\n");
printf("\t (B): 3x3 matrix\n\n");
char selection; //Stores matrix size selection
scanf(" %c", &selection);
int size; //Size of matrix
//Uses selection from user to determine value to assign to 'size'
if (selection == 'A' || selection == 'a'){
size = 2;
}
else if (selection == 'B' || selection == 'b'){
size = 3;
}
else{
printf("Your selection is invalid. Please start over.\n");
return 0;
}
printf("\nYou have selected a %dx%d matrix.\n\n", size, size);
//Initialize pointer array
int* matrix_ptr = (int*) malloc(size * sizeof(int*));
int** matrix = &matrix_ptr;
for (int i = 0; i < size; i++){
matrix[i] = (int*)malloc(size * sizeof(int));
}
readMatrix(matrix, size); //Sets up matrix by taking input from user
int calc = determinant(matrix, size); //Calculates determinant
printf("The %dx%d matrix is: \n\n", size, size);
//Displays the matrix on the console
for (int row = 0; row < size; row++){
for (int col = 0; col < size; col++){
printf("%d\t", matrix[row][col]);
}
printf("\n");
}
//Deletes stored data
for (int i = 0; i < size; i++){
free(matrix[i]);
}
free(matrix);
printf("\nThe determinant of the matrix is: %d\n", calc);
return 0;
}
determinant.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "matrix.h"
#include "determinant.h"
int determinant(int** matrix, int size){
int detm_calc; //Determinant calculation variable
//Determine which formula to use - 2x2 or 3x3 matrix.
if (size == 2){ //2x2 case
int a = matrix[0][0];
int b = matrix[0][1];
int c = matrix[1][0];
int d = matrix[1][1];
detm_calc = (a*d) - (b*c);
}
else{ //3x3 case
int a = matrix[0][0];
int b = matrix[0][1];
int c = matrix[0][2];
int d = matrix[1][0];
int e = matrix[1][1];
int f = matrix[1][2];
int g = matrix[2][0];
int h = matrix[2][1];
int i = matrix[2][2];
detm_calc = a*(e*i - f*h) - b*(d*i - f*g) + c*(d*h - e*g);
}
return detm_calc;
}
determinant.h
#ifndef DETERMINANT_H
#define DETERMINANT_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "matrix.h"
int determinant(int**, int);
#endif
matrix.c
#include <stdio.h>
#include <stdlib.h>
#include "matrix.h"
#include "determinant.h"
void readMatrix(int** matrix, int size){
for (int i = 0; i < size; i++){
for (int j = 0; j < size; j++){
printf("Please enter the integer for row %d column %d:\t", i+1, j+1);
scanf("%d", &matrix[i][j]);
}
printf("\n");
}
}
matrix.h
#ifndef MATRIX_H
#define MATRIX_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "determinant.h"
void readMatrix(int**, int);
#endif
Makefile
determinant: main.o determinant.o matrix.o
gcc main.o determinant.o matrix.o -o determinant.out
main.o: main.c
gcc -c main.c
determinant.o: determinant.c determinant.h
gcc -c determinant.c
matrix.o: matrix.c matrix.h
gcc -c matrix.c
The code shown above is supposed to create a determinant of a matrix however, it is not processing correctly as it infinitely loops. I assume something is wrong with the Makefile or the translation from C++ to C. Are there any notable errors that I am unable to spot? Thanks!
You are using
int* matrix_ptr = (int*) malloc(size * sizeof(int*));
int** matrix = &matrix_ptr;
Problems with this:
You are initializing matrix_ptr as a pointer to int, but allocating the memory for size*sizeof(int*), as though it would be an array of int*. So, allocated memory will depend on your hardware, and could be a mismatch with int memory size resulting in the wrong size of memory allocation.
int** matrix = &matrix_ptr; causes matrix to point to matrix_ptr, so when you are trying to write into matrix[1] in a loop - you are trying to write into an unallocated memory block, which will result in a segmentation fault.
int** matrix = (int**)malloc(size*sizeof(int*)); instead of these two lines will solve your problem
Note: I do not understand where it loops (I got a segfault with your code) and how the makefile can result in a runtime problem in your situation.

Is there a way to initialize all int array elements to zero except for loop

Is there a way to initialize all int array elements to zero except a for loop where we loop through to set values to zero. Here the size of array is decided by input of user.
#include <stdio.h>
int main() {
int num_cases = 0;
scanf("%d", & num_cases);
int arr_counter[num_cases];
for (int x = 0; x < num_cases; x++) {
arr_counter[x] = 0;
}
}
Yes, you can do that in multiple ways under C standard. For example:
memset() [Stack and Heap]
calloc() [Heap Only]
loops, e.g., do-while, while and for [Stack and Heap]
{ } [Stack Only]
1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int arr[10];
size_t len_arr = sizeof(arr) / sizeof(*arr);
memset(arr, 0, sizeof(arr));
for(size_t i = 0; i < len_arr; i++)
printf("%d\n", arr[i]);
return EXIT_SUCCESS;
}
Note: We can use memset() to set all values as 0 or -1 for integral data types also. It will not work if we use it to set as other values. The reason is simple, memset() works byte by byte.
2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int *arr = calloc(10, sizeof(int));
if(!arr)
{
fprintf(stderr, "bad ptr");
return EXIT_FAILURE;
}
for(size_t i = 0; i < 10; i++)
printf("%d\n", arr[i]);
free(arr);
return EXIT_SUCCESS;
}
Note: You need to keep track of arr maximum length.
Note: malloc() leaves garbage value in your pointer, whereas calloc() uses memset() to initialize them to 0.
Note: You need to free the heap allocated resource.
3
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
int arr[10];
size_t len_arr = sizeof(arr) / sizeof(*arr);
for(size_t i = 0; i < len_arr; i++)
arr[i] = 0;
for(size_t i = 0; i < len_arr; i++)
printf("%d\n", arr[i]);
return EXIT_SUCCESS;
}
Note: You can use any of your favorite loop.
4
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int arr[10] = {};
size_t len_arr = sizeof(arr) / sizeof(*arr);
for(size_t i = 0; i < len_arr; i++)
printf("%d\n", arr[i]);
return EXIT_SUCCESS;
}
Use calloc function available in stdlib.h
#include<stdio.h>
#include<stdlib.h>
int main(){
int num_cases;
scanf("%d", &num_cases);
int* arr = (int*)calloc(num_cases,sizeof(int));
return 0;
}
To initialize each element of Array you have two approaches:
If you are going for static memory allocation, you can initialize it like this:
int arr[10] = {};
If you are going for dynamic memory allocation, you can use calloc function.
int *arr = (int) calloc(numberOfElementsInArray,sizeOfEachElement);
In your case, it would be like:
int *arr_counter = (int*) calloc(num_cases,sizeof(int));
NOTE: You need to include malloc.h header file to use calloc function.

Pointing to arrays using void function

Sorry for that title. I really didn't know how to define this problem.
I was needed to declare integer array of N numbers and to fill it with random nums in void function. Then that array needs to be printed in main. The thing is that i am not allowed to use printf in void function so only way to print in main is to use pointers I guess. My knowledge is limited as I am beginner at pointers. Thx in advance and sorry for bad english.
Here is my code so far. When I compile it marks segmentation error.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void form();
int main()
{
int N, a[100];
printf("Input index: \n");
scanf("%d", &N);
form(N, &a);
printf("Array: \n");
for (int i = 0; i < N; i++) {
printf("a[%d] = %d", i, a[i]);
}
}
void form(int N, int *ptr[100])
{
srand(time(NULL));
for (int i = 0; i < N; i++) {
*ptr[i] = rand() % 46;
}
There are several issues in your code.
1) Your array decalaration form() is obsolete. Use proper prototype.
2) For declaring a VLA, declare it after reading N instead of using a fixed size array.
3) An array gets converted into a pointer to its first element when passed to a function. See: What is array decaying?
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void form(int, int*); /* see (1) */
int main(void) /* Standard complaint prototype for main.
If you need to pass arguments you can use argc, and argv */
{
int N;
printf("Input size: \n");
scanf("%d", &N);
int a[N]; /* see (2) */
form(N, a); /* see (3) */
printf("Array: \n");
for (int i = 0; i < N; i++) {
printf("a[%d] = %d", i, a[i]);
}
}
void form(int N, int *ptr) { /* Modified to match the prototype
srand(time(NULL));
for (int i = 0; i < N; i++) {
ptr[i] = rand() % 46;
}
}
So a couple things:
void form();
As Olaf was alluding to, this declaration is incorrect - you are missing the applicable parameters. Instead, it should be
void form(int N, int ptr[100]);
The main reason your program is crashing is because of the following line:
*ptr[i] = rand() % 46;
You are dereferencing the pointer at i, which is actaully giving you a number - what you want is to assign the value of the pointer at i the new random value:
ptr[i] = rand() % 46;
As related reading, see this question about passing an array in as a function parameter (basically, int ptr[] is the same thing as int * ptr)
Small modifications on your code:
1) Correction and simplification of parameter handling at function call. Just hand over "a", it's an array, so it is an address, you can use int *ptr, or int ptr[], or int ptr[100] in the formal parameter list for it. So you can use simply ptr[i] in your function.
2) Make a prototype for function from old-style declaration providing parameter list.
3) int i; declaration before the for loop - not mandatory, depends on your compiler standard
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
void form(int N, int *ptr);
int main()
{
int N, a[100];
printf("Input index: \n");
scanf("%d", &N);
form(N, a);
printf("Array: \n");
int i;
for (i = 0; i < N; i++) {
printf("a[%d] = %d", i, a[i]);
}
}
void form(int N, int *ptr)
{
srand(time(NULL));
int i;
for (i = 0; i < N; i++) {
ptr[i] = rand() % 46;
}
}

Dynamic array of int pointers causing segmentation fault

I found a segmentation fault in my C code and could not find a good explanation or solution for it after searching.
This first code gives me segmentation fault after printing 0.
#include <stdlib.h>
#include <stdio.h>
int main() {
int **defs = malloc(16 * sizeof *defs);
int i;
for (i = 0; i < 16; i++) {
printf("%d\n", i);
*defs[i] = i;
}
free(defs);
return 0;
}
This second code works fine.
#include <stdlib.h>
#include <stdio.h>
int main() {
int *defs = malloc(16 * sizeof defs);
int i;
for (i = 0; i < 16; i++) {
printf("%d\n", i);
defs[i] = i;
}
free(defs);
return 0;
}
These are just examples, not my actual code. I also tried doing pointer arithmetic but same result.
Could someone please explain this? Thank you.
In first code you have not allocated each of the int* memory blocks.
So, before assigning values to defs[i], you have to populate it with memory of type int*.
defs[i] = (int*)malloc(sizeof(int) * number_of_elements);
And then defs[i][some_index] = value.

Segmentaion fault in C when doing matrix multiplication

I use gsl random generator to generate 2 big matrices, and use gsl cblas to multiply them, but I always got Segmentation fault when the cblas operation begins. When I can't solve this, I then write the code below, using the very basic idea to do matrix multiplication, and I still got Segmentation Fault, but all the two can work all right when matrix is really a small one, I'm really puzzled about this.
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#define PI 3.1415926
void GenerateKey(int m, int n, int l, int q, float alpha)
{
// initialization
int i;
int j;
int k;
float *A;
float *S;
float *E;
float *B;
float sigma = (alpha * q ) / sqrt(2 * PI);
A=(float*)malloc(sizeof(float)*(m*n));
S=(float*)malloc(sizeof(float)*(n*l));
B=(float*)malloc(sizeof(float)*(m*l));
E=(float*)malloc(sizeof(float)*(m*l));
// init A
for(i = 0; i < m*n; i++)
{
A[i]=0;
}
printf("\n");
// init S
for(i = 0; i < n*l; i++)
{
S[i]=0;
}
printf("\n");
// init E
for(i = 0; i < m*l; i++)
{
E[i]=0;
}
printf("\n");
float po;
for(i = 0; i < m; i++)
{
for(j=0; j<l; j++)
{
po=0;
for(k=0; k<n; k++)
{
po +=A[i*m+k]*S[k*n+j];
}
po += E[i*m +j];
B[i*m+j]=((int)po) % q;
}
}
printf("Game over");
printf("\n");
free(A);
free(B);
free(S);
free(E);
}
int main()
{
GenerateKey(2680,191,64,72973,0.000551);
return 0;
}
When you're doing i*m+j, shouldn't that be i*l+j ? Similarly with i*m+k should be i*l+k and k*n+j should be k*l+j
The reason being, take for example E = (float*)malloc(sizeof(float)*(m*l)), so you have m rows and l columns (or vise versa), so if you are iterating over the m dimension you need to be multiplying your m iterator (i in this case) by the stride of your matrix in that dimension, which is l.
You don't check the malloc() return values, so my guess is that one or more allocation is failing and you're dereferencing NULL. Another possibility is of course an indexing error, so you acccess out of bounds.
You incorrectly compute an element index for all the matrices.
When you have an MxN matrix which is allocated as an 1-dimensional array, the index for an element (i,j) is i*N+j. Instead, you're computing it as i*M+j.

Resources