i have made a program that creates 2d array.
the code below works well on visual studio & turbo c:
#include<stdio.h>
#include<stdlib.h>
int **allocarr(int **arr, int row, int col){
int i;
arr=calloc(row, sizeof(int));
for(i=0; i<row; i++){
arr[i]=calloc(col, sizeof(int));
}
return arr;
}
void freearr(int **arr, int row, int col){
int i;
for(i=0; i<row; i++) free(arr[i]);
free(arr);
}
void printarr(int **arr, int row, int col){
int i, j;
for(i=0; i<row; i++){
for(j=0;j<col;j++){
printf("\t%d", arr[i][j]);
}
printf("\n\n");
}
}
int main(){
int **arr=NULL;
arr=allocarr(arr, 3, 3);
arr[2][2]=8;
printarr(arr, 3, 3);
freearr(arr,3, 3);
return 0;
}
but it does not work on mac os x gcc and mingw gcc.
everything compiles fine without any warning and errors(-Wall & -Wextra),
but it crashes on runtime...
in gdb and lldb, it says that free() is freeing a non-allocated memory.
after allocating a pointer array, when i allocate memory after that, exactly 2 of the memory block(is this the right word?) will have random values that cannot be initialized.
i tried allocating another array before i assign it to the pointer array.
it prints fine(no 2 random values), but will still occasionally crash when assigning values on it.
why is this happening?
This
arr=(int **)calloc(row, sizeof(int));
should be
arr = calloc(row, sizeof(int*));
(note that the cast is not required in C and actually discouraged)
So on implementations where the size of a pointer is not the size of int (e.g. on x64 machines), you will invoke undefined behavior when you read outside the bounds of allocated memory.
You might consider not using an explicit type as the operand of sizeof.
arr = calloc(row, sizeof*arr);
This lets the compiler deduce the type and will help you avoid errors like this.
Related
I am writing C code to take user parameters and build an integer array from them. I ask the user to provide the array length and each element's value.
Running the following code causes an error at the printArray() function call. Following the debugger into printArray(), the Segmentation Fault itself occurs at printf("%d", intArray[i])
NOTE: The array is correctly printed when I copy the printArray() code into main() instead of making a function call. This makes me think that I have an issue with global variables and/or pointers. I am still learning C, so your guidance is appreciated.
How can I fix this? See debugger output at the bottom for more info.
void printArray();
int arraySize;
int* intArray;
int main() {
printf("Enter array length:\n");
scanf("%d", &arraySize);
int* intArray = (int*) malloc(sizeof(int)*arraySize);
printf("Enter an integer value for each array element:\n");
for (int i = 0; i < arraySize; i++) {
printf("Enter element %d:\n", i);
scanf("%d", &intArray[i]);
}
printArray();
return 0;
}
void printArray() {
printf("[");
for (int i = 0; i < arraySize; i++) {
printf("%d", intArray[i]);
}
printf("]\n");
}
I think you have redeclared intArray variable in main()
int* intArray = (int*) malloc(sizeof(int)*arraySize);
by doing this, the scope of this variable is only in the main function and printArray() does not know about this definition. So printArray() tries to access intArray variable which you have declared globally(which does not have definition) and thus leading to segmentation fault.
So just give intArray = (int*) malloc(sizeof(int)*arraySize);
randomAssign(int **grid, int size){
int m = rand()%size;
int n = rand()%size;
grid[m][n] = 1;
}
int main()
{
srand(time(NULL));
int i, j, size;
scanf("%d", &size);
int grid[size][size];
for(i=0; i<size; i++){
for(j=0; j<size; j++){
grid[i][j] = 0;
}
}
randomAssign(grid,size); //warning
return 0;
}
I am getting warning when i call the function. I tried all i can do but i couldn't find the mistake. Where is the mistake? Regards...
Arrays and pointers are different. An array is a series of contiguous elements of a particular type. A pointer is a small object that holds the address of another object.
Your function expects a pointer that points to another pointer. However you tried to supply an array to it. This can't possibly work.
One way to fix your code would be to make the function accept a pointer to an array (not a pointer to a pointer). This could be written:
void randomAssign(int size, int grid[size][size])
This is actually the same as having int (*grid)[size], the first size is redundant (see here for detail) however it serves some documentary purpose.
I'm trying to allocate memory to a matrix in a function and then print its values.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void cria_ilhas(int** ilhas, int n){
int i, p;
ilhas = (int**) malloc(n*sizeof(int*));
for (i=0;i<n;i++){
ilhas[i] = (int*) malloc(n*sizeof(int));
for (p=0; p<n; p++)
ilhas[i][p] = 4;
}
printf("value %d\n",ilhas[0][0]);
}
void main(){
int n=5, i, j;
int **ilhas;
cria_ilhas(ilhas, n);
for(i=0; i<n; i++){
for(j=0;j<n;j++){
printf("%d ",ilhas[i][j]);
}
printf("\n");
}
}
But this is the output:
value 4
Segmentation fault
Why i'm having segmentation fault?
How can I use memset in this kind of matrix?
You’re doing it almost correctly. When you’re calling cria_ilhas, you’re passing in the variable ilhas, and expecting that when you change it inside of the function, that effects the variable in main, too. Unfortunately, C doesn’t work that way.1
What you’ll want to do is remove the ilhas parameter from cria_ilhas and stop passing it in when you call it in main. Then just declare ilhas as a local variable in cria_ilhas. To get the value back to main, you’ll need to return it from cria_ilhas, and in main, when you call it, assign ilhas to its result.
1 Side note: if you were using C++, you could make it work by changing the parameter from int **ilhas to int **&ilhas.
Change your code to this shape and tell me if it worked
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int** cria_ilhas( int n){
int i, p;
int **ilhas
ilhas = (int**) malloc(n*sizeof(int*));
for (i=0;i<n;i++){
ilhas[i] = (int*) malloc(n*sizeof(int));
for (p=0; p<n; p++)
ilhas[i][p] = 4;
}
printf("value %d\n",ilhas[0][0]);
return ilhas;
}
void main(){
int n=5, i, j;
int **ilhas;
ilhas = cria_ilhas(n);
for(i=0; i<n; i++){
for(j=0;j<n;j++){
printf("%d ",ilhas[i][j]);
}
printf("\n");
}
}
I think it should work for you, your code is much likely to be true but the problem is you have defined a large structure in heap (ilhas definition in main method) and you sent it address to a method ( call by reference) which suppose to allocate memory for it from stack segment but not heap, if you pass the address of a simple type variable to a method, it woundnt be a problem but allocating memory for array's will raise segmentation problem.
I am a newbie and novice to C programming and learning pointers and implementation of 2-dimensional arrays using pointers. I am getting a runtime error while executing the following program which compiles without any complaint but crashes at run-time with the message "Segmentation fault (core dumped)". If I run the program without using malloc(for dynamic memory allocation) it runs perfectly. I am using gcc compiler on Ubuntu linux.
#include<stdio.h>
#include<stdlib.h>
#define ROW 3
#define COL 3
main()
{
int *arr[ROW];
int i,j;
arr[ROW] = (int *) malloc(COL * sizeof(int)); //dynamic memory allocation
printf("\nEnter values\n\n");
for(i=0;i<ROW;i++)
{
for(j=0;j<COL;j++)
scanf("%d",(*(arr+i)+j));
}
printf("\nEntered values are\n");
for(i=0;i<ROW;i++)
{
for(j=0;j<COL;j++)
printf("\t%d",*(*(arr+i)+j));
printf("\n");
}
printf("\n");
}
The program crashes with the following message at run time:
Segmentation fault (core dumped)
The following version of the program (without malloc) executes perfectly without any error
#include<stdio.h>
#include<stdlib.h>
#define ROW 3
#define COL 3
main()
{
int *arr[ROW][COL];
int i,j;
printf("\nEnter values\n\n");
for(i=0;i<ROW;i++)
{
for(j=0;j<COL;j++)
scanf("%d",(*(arr+i)+j));
}
printf("\nEntered values are\n");
for(i=0;i<ROW;i++)
{
for(j=0;j<COL;j++)
printf("\t%d",*(*(arr+i)+j));
printf("\n");
}
printf("\n");
}
In the first code you are not allocating correctly your array. Here you are only allocating the last ROW/COL of your matrix, you should allocate this way:
for(i=0; i<ROW; ++i)
arr[i] = (int *) malloc(COL * sizeof(int));
And by the way you should be aware that anything that has been allocated dynamically has to be desallocated. Ifnot you are getting a memory leaks:
for(i=0; i<ROW; ++i)
free( arr[i] );
The problem in your first segment of code is this line:
arr[ROW] = (int *) malloc(COL * sizeof(int)); //dynamic memory allocation
You have undefined behaviour everywhere. First, with arr[ROW] you access outside the bounds of the array. Second, if you want allocate a ROW number of pointers, then you need use a loop and store in arr.
for(i=0;i<ROW;i++)
arr[i]=malloc(COL * sizeof(int));
free() them once you are done with it and don't cast the return value of malloc().
Your second program is not correct either. The array of pointers is not initialized at all. They pointers don't point valid memory locations. You need to allocate memory for each of the pointers or simply use a proper array like: int arr[ROW][COL].
I want to use this code in a more complex problem, but I didn't get it to work. Why isn't my matrix getting printed?
#include <stdio.h>
#include <stdlib.h>
void print_mat(int **a, int n)
{
printf("\n");
int k,t;
for (k=1;k<=n;k++)
{
for (t=1;t<=n;t++)
printf("%d ", a[k][t]);
printf("\n");
}
}
int main()
{
int i,j,n,**a;
printf("Chess board size=");
scanf("%d", &n);
a=(int **)malloc(n*sizeof(int));
for (i=1;i<=n;i++)
a[i]=(int*)malloc(n*sizeof(int));
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
a[i][j]=-1;
print_mat(a,n);
return 0;
}
You should first malloc for size of int * not int , change
a = ( int ** )malloc( n * sizeof( int ) );
to
a = malloc( n * sizeof( int* ) ); //also no need to cast.
Also, as #Russell Borogove suggested, change loop as for( i = 0; i < n; i++ ) instead of from 1 to n.
You will want to get in the habit of using zero-based indexes with C arrays, and display them as if they were 1-based only when presenting things to users.
Change your for (i=1;i<=n;i++) loops to for (i=0;i<n;i++). Likewise with j, k, and t.
As currently written, a[n] isn't an allocated pointer, and a[0][n] isn't within the a[0] buffer allocation. The result (gcc 4.2.1 on OSX 10.7.5) is a program crash.
The line
a=(int **)malloc(n*sizeof(int));
should read
a=malloc(n*sizeof(int *));
a=(int **)malloc(n*sizeof(int));
change to a= mallo(n*sizeof(int*))
On some systems int and int* (pointers) can have same size but here may be this is creating the problem.
Also
for (i=1;i<=n;i++)
for (j=1;j<=n;j++)
a[i][j]=-1;
change it to
for (i=0;i<n;i++)
for (j=0;j<n;j++)
a[i][j]=-1;