problem with 2d array mallocation (segmentation fault) - c

I tried to malloc a 2d array, but it gdb gives me Segmentation fault in line 8. It seems like something is wrong with if (A[i+x][j+y]!=A[i][j].
By the way: This program should print out the dimensions of the maximum square-sized sub-matrix of an input matrix, such that all its digits are equal matrix, such that all its digits are equal.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int same_surrounding(int **A, int i, int j, int size){
for (int x=0; x<size; x++){
for (int y=0; y<size; y++){
if (A[i+x][j+y]!=A[i][j])
return 0;
}
}
return 1;
}
int main(){
int n, i, j, sub, max_sub;
int **A;
scanf("%d", &n);
A=malloc(sizeof*A*n);
for (i=0; i<n; i++){
A[i]=malloc(sizeof**A*n);
}
for (i=0; i<n; i++){
for (j=0; j<n; j++){
scanf("%d", &A[i][j]);
}
}
for (i=0; i<n; i++){
for (j=0; j<n; j++){
sub=1;
while (sub<n&&same_surrounding(A, i, j, sub)){
if (sub>max_sub)
max_sub=sub;
sub++;
}
}
}
printf("%d", max_sub);
for (i=0; i<n; i++){
free(A[i]);
}
free(A);
return 0;
}

There are mainly 2 things wrong with this code:
Your program is checking for submatrices beyond the dimension of input matrix n. for example, if n=5,i=3,j=0 and sub=3 you can easily see that your code is checking for numbers in A[i+x][j+y] i.e. upto A[5][2] which is out of bound of A. You need to check this before sending it to same_surrounding(). For that all you need to do is slightlt change the while loop:
while (sub<=n && i+sub<n && j+sub<n && same_surrounding(A, i, j, sub)){...}
Always initialize your variables. Here you didn't initialize max_sub variable. When you don't initialize your variables, it contains random garbage value. For example if the garbage value is 478231 and you are looking for largest square matrix of 5x5 matrix, you'll never reach the condition if (sub>max_sub) and as a result max_sub will never update. That's why always initialize your variable with a safe value, for example, max_sub=0.
Also, as a warning, you should use sizeof() instead of explicitly writing the number of bytes necessary for memory allocation. Because they might change depending on computer architecture.
A=(int**) malloc(sizeof(int*)*n);
for (i=0; i<n; i++){
A[i]=(int*)malloc(sizeof(int)*n);
}
Here's the working version of your code. All I did was some { } cleanup. If you have just one statement under for, while, if etc., you don't really need the braces.

Related

Why do I get segmentation error when the number of rows/columns exceed 5?

I am trying to solve the following problem -
Given a matrix of size M * N. Find the transpose of the matrix.
I intend to store the M*N matrix in an array of pointers and then use a function to return another array of pointers that contains the transpose of the original matrix. Here is the code I used (the code is in C language) -
#include<stdio.h>
#include<stdlib.h>
int **transpose(int **a, int m, int n);
int main()
{
int **array, m, n;
scanf("%d%d", &m, &n);
array=(int **)malloc(m*sizeof(int)); //allocating rows
for(int i=0; i<m; i++){
*(array+i)=(int *)malloc(n*sizeof(int)); //allocating columns
}
int i, j;
for(i=0; i<m; i++){
for(j=0; j<n; j++){
scanf("%d", *(array+i)+j); //reading input
}
}
int **tranp=transpose(array, m, n);
for(i=0; i<n; i++){
for(j=0; j<m; j++){
printf("%d ", *(*(tranp+i)+j)); //printing output
}
printf("\n");
}
return 0;
}
int **transpose(int **a, int m, int n)
{
int **b;
b=(int **)malloc(n*sizeof(int)); //allocating n rows for transpose
int i, j;
for(i=0; i<n; i++){
*(b+i)=(int *)malloc(m*sizeof(int)); //m columns for transpose
}
for(i=0; i<n; i++){
for(j=0; j<m; j++){
*(*(b+i)+j)=*(*(a+j)+i); //b[i][j] is assigned a[j][i]
}
}
return b; //the pointer to b[0][0] is returned
}
I first declared an array of pointers int **array and used the standard library malloc function to dynamically allocate M rows and N columns. Then I read the input and used the function transpose that has a return type int ** to generate the transpose of the array and assign it to the pointer tranp and print the transposed array.
However, this code works perfectly fine and prints the transposed array for M<5 and N<5. Whenever M>=5 or N>=5, I get the following message -
Process returned -1073741819 (0xC0000005)
I looked up about it and apparently (0xC0000005) is the error code returned because I am illegally accessing memory locations. I do not understand where have I gone wrong here. Why is it that this code works for all M and N less than 5 and fails otherwise?

Dynamic Memory Allocation Of an Array in C [duplicate]

This question already has answers here:
Why does scanf ask twice for input when there's a newline at the end of the format string?
(7 answers)
Closed 1 year ago.
I have been trying to write a simple code wherein the array is allocated dynamically. Every time I specify the side of the array as n(suppose 4) and proceed to type the given input, it takes exactly n+1(5 in this case) inputs from me but as the output, it prints n(4) elements.
Here's the main function I wrote:
int main() {
int *arr, n;
scanf("%d", &n); //n is the size
arr = (int *)malloc(n*sizeof(int));
for(int i=0; i<n; i++) {
scanf("%d ", &arr[i]);
}
for(int i=0 ; i<n; i++) {
printf("%d ", arr[i]);
}
}
I've also tried doing the code by initializing i in the first loop as 1, and in that way it takes exactly n inputs but it gives a weird output, something like this:
7953616 1 2 3
in those two lines
scanf("%d ", &arr[i]);
printf("%d ", arr[i]);
you have %d instead of %d
also you need to use free() from stdlib library as after you finish using the pointer you need to free the memory in order to reuse it again otherwise this will happen
final code
#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr, n;
scanf("%d", &n); //n is the size
arr = (int *)malloc(n*sizeof(int));
for(int i=0; i<n; i++)
scanf("%d", &arr[i]);
for(int i=0 ; i<n; i++)
printf("%d", arr[i]);
free(arr);
}

Error in array allocation in C

i've try to compile this simple program, it will alloc a dyamic array and return it with a multiple of 5 in every location. but it doesn't work, it report me an error in the pointer.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char const *argv[]) {
int n;
int i;
int* ptra;
scanf("%d", &n);
ptra = malloc(n*(sizeof(int)));
for(i=0; i<=n; i++){
ptra[i] = (5*(i+1));
printf("%d\n", ptra[i]);
}
return 0;
}
Index range for ptra must be from 0 to n-1 (both inclusive). But here:
for(i=0;i<=n;i++){
you are going out of bounds, which is undefined behaviour. Change it to:
for(i = 0; i < n; i++) {
Note: Always check the return of all the standard functions for failures (scanf() and malloc() in your code).
Your for loop is going one step beyond the limit: must go as long as i<n and not i<=n
try doing:
for(i=0; i<n; i++){

Using free() creates segmentation fault

I'm having an issue that I cannot seem to fix with my memory allocations.
I create 3 dynamically allocated arrays (ipiv,k,b) using malloc, but when I try and free them, I get a seg fault. If I don't free them, the code works fine (but if I run too many iterations, I run out of memory).
Here is the code... I've taken out all of the parts that do not use the 3 arrays, since the code is pretty long.
#include<stdio.h>
#include <string.h>
#include<stdlib.h>
#include<math.h>
#include <mpi.h>
#include "mkl.h"
#define K(i,j) k[(i)+(j)*(n)]
void dgesv_( const MKL_INT* n, const MKL_INT* nrhs, double* a,
const MKL_INT* lda, MKL_INT* ipiv, double* b,
const MKL_INT* ldb, MKL_INT* info );
int main()
{
int *ipiv=malloc(n*sizeof(int));
for (i=0; i<n; i++) {
ipiv[i]=0;
}
for (globloop=0; globloop<=lasti; globloop++) {
double a[ndofs];
double rhs[ndofs];
double F[ndofs];
double *k=malloc(n*n*sizeof(double));
//var for stiffness matrix (this is the one acutally fed to dgesv)
//see define at top
for (i=0; i<n; i++) {
for (j=0; j<n; j++) {
K(i,j)=0.0;
}
}
//bunch of stuff modified, a,rhs,and F filled... ect
while (sos>=ep && nonlinloop<=maxit) {
double KFull[ndofs][ndofs];
for (i=0; i<ndofs; i++) {
for (j=0; j<ndofs; j++) {
KFull[i][j]=0.0;
}
}
//KFull filled with values..
//trim the arrays to account for bcs
double *b=malloc(n*sizeof(double));
for (i=0; i<n; i++) {
b[i]=rhs[i+2];
}
//k array filled
//see define above
for (i=0; i<n; i++) {
for (j=0; j<ndofs-2; j++) {
K(i,j)=KFull[i+2][j+2];
}
}
//SOLVER
dgesv_(&n,&one,k,&n,ipiv,b,&n,&info);
//now we must take our solution in b, and place back into rhs
for (i=0; i<n; i++) {
rhs[i+2]=b[i];
}
nonlinloop++;
free(b);
}
free(k);
}
free(ipiv);
return 0;
}
Freeing any one of these 3 variables gives me a segmentation fault. I am super-confused about this.
If n=ndofs-4 (as mentioned in the OP's comment) then ndofs-2 is greater then n. And then the code will be corrupting the memory at
K(i,j)=KFull[i+2][j+2];
because j runs up to ndofs-2-1 and K is (only) defined to be K[0..n-1][0..n-1].

Using scanf() to input a square of integers

I am coding a c project, that needs that the user enters a N*N square of integers : that's to say an input of N lines of N integers. The algo works fine.
Now I want the user to input N lines of N integers each of consecutive integers are separated by a space. Here, I don't have the right usage of scanf, because I tried to declare integers array but I was not able to deal with the spacing.
I tried something like this, very unnatural and failing :
int i=0;
int j=0;
int N;
scanf("%d",&N);
char c[N][2*N-1];
while(i < N){
scanf("%s",&c[i]);
i++;
}
i=0;
j=0;
while (i<N){
while (j<N){
c[i][j]=c[i][2*j]-48;
j++;
}
j=0;
i++;
}
Can someone help ?
Best,
Newben
If I understood what your original code was supposed to do then this code should actually do it (and print it out again just to prove it worked).
You need to dynamically allocate the array since it's variable size ( In C99 you could use variable sized arrays on the stack but that's really a different discussion ).
scanf will automatically ignore white-space between the integers (including spaces and new-lines) so you don't need to parse that out manually.
#include <stdlib.h>
#include <stdio.h>
int main()
{
int i=0, j=0, N;
int **c;
scanf("%d",&N);
c = malloc(N*sizeof(int*));
for (i=0;i<N;i++)
{
c[i] = malloc(N*sizeof(int));
for (j=0;j<N;j++)
{
scanf("%d",&c[i][j]);
}
}
for (i=0;i<N;i++)
{
for (j=0;j<N;j++)
{
printf("%d ",c[i][j]);
}
printf("\n");
free(c[i]);
}
free(c);
return 0;
}
C99 alternative without malloc/free for completeness (I'v never liked this C99 feature since there's no way to check that the was/is enough space on the stack):
#include <stdlib.h>
#include <stdio.h>
int main()
{
int i=0, j=0, N;
scanf("%d",&N);
int c[N][N];
for (i=0;i<N;i++)
{
for (j=0;j<N;j++)
{
scanf("%d",&c[i][j]);
}
}
for (i=0;i<N;i++)
{
for (j=0;j<N;j++)
{
printf("%d ",c[i][j]);
}
printf("\n");
}
return 0;
}

Resources