I am writing this simple code for dynamically allocated 2D array and displaying it. When I execute this program, it gives garbage value in the first row. How is that? Any errors in my program?
#include <stdio.h>
#include <stdlib.h>
int main()
{
int **ptr, limit, i, j;
printf("Enter the limit: ");
scanf("%d", &limit);
ptr = (int **) malloc(limit * (sizeof(int)));
for(i=0; i<limit; i++)
{
*(ptr+i) = (int *) malloc((i+1) * sizeof(int));
for(j=0; j<=i; j++)
{
ptr[i][j] = i;
}
}
for(i=0; i<limit; i++)
{
for(j=0; j<=i; j++)
{
printf("%d ", ptr[i][j]);
}
printf("\n");
}
return 0;
}
Output:
Enter the limit: 4
0
1 1
2 2 2
3 3 3 3
Enter the limit: 5
9478320
1 1
2 2 2
3 3 3 3
4 4 4 4 4
If I try to print the 2D array with the limit is less than or equal to 4, it works fine. What am I missing here..
Thanks
Maybe there are other issues as well; but one thing is for sure - you are allocating the wrong size for the pointer elements:
ptr = (int **) malloc(limit * (sizeof(int)));
though there should be limit objects of pointers to int, you are allocating ints. So it needs to be...
ptr = malloc(limit * (sizeof(int*)));
BTW: In C, avoid casting the result of malloc.
Related
I am trying to code a array with dynamic rows and columns (multi-dimensional).
This is what I've tried:
#include <stdio.h>
#include <stdlib.h>
#define LEN(arr) ((int) (sizeof (arr) / sizeof (arr)[0]))
int main() {
int size, q = 0;
// get arr size from stdin
scanf("%d", &size);
int *arr[size];
for (int i=0; i<size; i++) {
int len, element = 0;
// get length of column from stdin
scanf("%d", &len);
arr[i] = malloc(len * sizeof(int));
for(int j=0; j<len; j++) {
// get each column's element from stdin and append to arr
scanf("%d", &element);
arr[i][j] = element;
}
}
for (int i=0; i< LEN(arr); i++)
printf("%d\n", LEN(arr[i]));
}
stdin:
2
3 4 5 6
4 1 2 3 4
The first line of input is the size/amount of arrays to be stored in arr (2),
the following lines begin with the size of the columns (3, 4) followed by the elements to store (4 5 6, 1 2 3 4) in each column.
stdout:
2
2
When I run this program with the output is 2 meaning each column's length is 2, this is unintended. I am seeking for a solution to output the correct column lengths. What am I doing wrong?
The intended stdout is:
3
4
arr is an array, so sizeof(arr) gives you the size in bytes of the array as expected.
arr[i] is not an array however. It is a pointer, specifically a int *. So sizeof(arr[i]) gives you the size in bytes of an int *.
When you allocate memory dynamically, you need to keep track of how much space was allocated. You can do this by maintaining a separate array with size size of each subarray.
int *arr[size], arr_len[size];
...
for (int i=0; i<size; i++) {
...
arr[i] = malloc(len * sizeof(int));
arr_len[i] = len;
...
}
for (int i=0; i< LEN(arr); i++)
printf("%d\n", arr_len[i]));
I must write a function in C that takes in a matrix (src) and 2 integer values(x,y), then gives out a matrix which contains src x by y times.
For example
3 5
2 1
with (2,3) is going to be
3 5 3 5
2 1 2 1
3 5 3 5
2 1 2 1
3 5 3 5
2 1 2 1
I am given the structure
struct Mat {
int cols; // number of columns
int rows; // number of rows
int** row_ptrs; // pointer to rows (the actual matrix)
} Mat;
and wrote this function:
#include "exercise_1.h"
#include <stdlib.h>
Mat* matrixRepeat(Mat* src, int num_row_blocks, int num_col_blocks)
{
Mat *newMat = malloc(sizeof(Mat));
newMat->rows = src->rows * num_row_blocks;
newMat->cols = src->cols * num_col_blocks;
newMat->row_ptrs = calloc(newMat->rows, sizeof(int*));
for(int i = 0; i < newMat->cols; i++)
newMat->row_ptrs[i] = calloc(newMat->cols, sizeof(int));
for(int i = 0; i < newMat->rows; i++)
for(int j = 0; j< newMat->cols; j++)
newMat->row_ptrs[i][j] = src->row_ptrs[i%src->rows][j%src->cols];
return newMat;
}
Then I am given some test programs: half of them works just fine, the other tough gives me segfault. I know for sure that the tests are correct, so there must be a problem in my program. Can you help me find it?
The condition in the loop
for(int i = 0; i < newMat->cols; i++)
^^^^^^^^^^^
newMat->row_ptrs[i] = calloc(newMat->cols, sizeof(int));
is wrong. There must be
for(int i = 0; i < newMat->rows; i++)
^^^^^^^^^^^
newMat->row_ptrs[i] = calloc(newMat->cols, sizeof(int));
Note: I think you mean
typedef struct Mat {
^^^^^^^
int cols; // number of columns
int rows; // number of rows
int** row_ptrs; // pointer to rows (the actual matrix)
} Mat;
Trying to read an input .txt file with using fscanf, and store the line content to the int variable, array, and 2D array, so I can use the value to do computation later. I think the problem over here is because I did not handle the "EOF" with using fscanf?
Here is my code:
int main(){
FILE *fp;
int n; // # resources
int m; // # processes
int avail[n];
int max[m][n], allo[m][n];
char temp1[10];
fp = fopen("test.txt", "r");
if (fp == NULL){
exit(EXIT_FAILURE);
}
fscanf(fp, "%d %d", &n, &m);
printf("%d %d", n, m);
printf("\n");
// Store the second line content to allo[]
for(int i = 0; i < n; i++){
fscanf(fp, "%s", temp1);
avail[i] = atoi(temp1);
printf("%d ", avail[i]);
}
printf("\n");
// Store the line3-7 content to 2D max[][]
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
fscanf(fp, "%s", temp1);
max[i][j] = atoi(temp1);
printf("%d ", max[i][j]);
}
printf("\n");
}
// Store the line8-12 content to 2D allo
for(int i = 0; i < m; i++){
for(int j = 0; i < n; j++){
fscanf(fp, "%s", temp1);
allo[i][j] = atoi(temp1);
printf("%d ", allo[i][j]);
}
printf("\n");
}
fclose(fp);
return 0;
}
Here is the .txt input file:
3 5
9 6 3
5 5 2
4 1 3
8 3 4
5 4 2
4 4 3
0 1 0
1 1 0
1 0 2
0 0 1
1 2 2
And here is the output:
3 5
9 6 3
5 5 2
4 1 3
8 3 4
5 4 2
4 4 3
Segmentation fault: 11
The problem is here:
int n; // # resources
int m; // # processes
int avail[n];
int max[m][n], allo[m][n], need[n][m];
n and m are not initialized when you declare the 2D array max. Try printing n and m before int max[m][n];, etc. and you will see that they contain garbage values.
As a result, Undefined Behavior is what you are experiencing, since you can't really tell what the size of your array is.
Change it to this:
int n; // # resources
int m; // # processes
fscanf(fp, "%d %d", &n, &m);
printf("%d %d", n, m);
int avail[n];
int max[m][n], allo[m][n], need[n][m];
Now when you create your arrays, n and m will be initialized with the values read from the file.
If you want to declare your arrays before reading n and m, then you should use pointers, read n and m and then dynamically allocate the arrays.
You declare int max[m][n], allo[m][n], need[n][m] while m and n are not set yet, so they are of unknown size. They will not resize themselves after the sizes are set. So writing to these will give you "undefined behaviour"
Since m,n is not initialized when you declared your arrays at the top of your file:
int avail[n];
int max[m][n], allo[m][n], need[n][m];
as #WeatherVane stated in the comments, you will get undefined behavior. Maybe you are overwriting some other part of the programs memory (who knows it is undefined!).
If you need dynamic array creation you should do something like the following:
int* avail;
...
fscanf(fp, "%d %d", &n, &m);
avail = (int*)malloc(n*sizeof(int));
When you initialize max,allo and need. the value of n and m is not defined.
You can define max, allo and need as int**.
After you have scanned the value of n and m, you can invoke the below function to allocate memory for above 2D arrays.
int ** get2DintArray(int r, int c){
int **arr = (int **)malloc(r * sizeof(int *));
for (i=0; i<r; i++)
arr[i] = (int *)malloc(c * sizeof(int));
return arr;
}
For. e.g:-
allo = get2DintArray(m,n);
need = get2DintArray(n,m);
This approach will be handy for higher values of n and m, where the stack memory may not be sufficient, because you are using heap memory in this case.
I want to change rows into column and column into rows of that 2-D array
I want a program which takes input and gives output as below.
Input: 1 2 3
4 5 6
Output: 1 4
2 5
3 6
Input: 1 2 3
4 5 6
7 8 9
Output: 1 4 7
2 5 8
3 6 9
I did a sample which in hardcoded array as below
int main()
{
int i,j;
int grades[2][3] = { {55, 60, 65},
{85, 90, 95}
};
for( j = 0; j < 3; j++)
{
for( i = 0; i < 2;i++)
{
printf("%d\t",grades[i][j]);
}
printf("\n");
}
return 0;
}
Its long time since i programmed in C , is there anyway we can make things dynamic or better way of doing the same. Right now its hardcoded.
I remember we have to use malloc or so , is that right.
psuedo code is also fine.
Taking from Zhehao Mao user and fixing it, the would look like this:
#include <stdio.h>
void transpose(int *src, int *dest, int rows, int cols){
int i,j;
for(i=0; i<rows; i++){
for(j=0; j<cols; j++){
dest[j*rows + i] = src[i*cols + j];
}
}
}
int main(void)
{
int oldar[2][3] = {{1,2,3},{4,5,6}};
int newar[3][2];
transpose(&oldar[0][0], &newar[0][0], 2, 3);
int i, j;
for(i = 0; i < 2; i++)
{
for(j = 0; j < 3; j++)
printf("%d ", oldar[i][j]);
printf("\n");
}
for(i = 0; i < 3; i++)
{
for(j = 0; j < 2; j++)
printf("%d ", newar[i][j]);
printf("\n");
}
}
The reason the original post can't work is that int ** expects a pointer to pointers like:
int **a ---------> int *int1 --> 1
int *int2 --> 2
int *int3 --> 3
which is not what we get when we say int a[n][m]. Rather we have the array organized like this
a[0][0]
\
1 2 3 4 5 6
\___/ \___/
"a[0]" / \____ "a[1]"
or something like this. The picture likely does not explain it well, but currently I can't do better.
void main()
{
clrscr();
int in[10][10];
int out[10][10];
int row,column,i,j;
printf("enter row");
scanf("%d",&row);
printf("Enter column");
scanf("%d",&column);
//storing values in matrix
for(i=1;i<=row;i++)
{
for(j=1;j<=column;j++)
{
printf("Enter (%d,%d)th value",i,j);
scanf("%d",&in[i-1][j-1]);
}
}
//show stored values
printf("\ninput is\n\n");
for(i=0;i<row;i++)
{
for(j=0;j<column;j++)
{
printf("%d\t",in[i][j]);
}
printf("\n");
}
//show transposed value. it is also stored in out matrix
printf("\nOutput is\n\n");
for(i=0;i<column;i++)
{
for(j=0;j<row;j++)
{
printf("%d\t",in[j][i]);
out[i][j]=in[j][i];
}
printf("\n");
}
getch();
}
//////////////////////////////////////
input matrix is stored in in[][] matrix and output matrix stored in out[][] matrix.
this program will work for any matrix with row and column below 10 if we increase the matrix variable value ,it will work for larger matrix also .
Here is a rather naive implementation. I'm pretty sure there are more efficient ways, but this is all I could think of.
void transpose(int **src, int **dest, int rows, int cols){
int i,j;
for(i=0; i<rows; i++){
for(j=0; j<cols; j++){
dest[j][i] = src[i][j];
}
}
}
int main(void){
int oldar[2][3] = {{1,2,3},{4,5,6}};
int newar[3][2];
transpose(oldar, newar, 2, 3);
}
Double pointers can represent double arrays, so there is no need to allocate on the heap here.
This is a half-done program the way I would do it in C:
int main()
{
int **data;
int rows = 0,
columns = 0;
char in[256];
int *irow;
// Get user input.
for(rows = 0; 1; ++rows)
{
scanf("%255s", in);
if(strcmp(in, "exit") == 0)
break;
// Parse row here. Remove all the tabs. Set column count.
for(int icolumn = 0; 1; ++icolumn)
{
/* ... */
}
// Set columns if first time.
if(rows == 0)
columns = icolumn;
// Check to make sure user inputs correct amount of columns.
if(columns != icolumns)
{
printf("OMG! The user is a hacker!\n");
break;
}
// Push parsed row into **data.
data[rows] = irow;
}
// Display output.
for(int i = 0; i < columns; ++i)
{
for(int j = 0; j < rows; ++j)
{
printf("%d\t", data[j][i]);
}
printf("\n");
}
return 0;
}
I'm a C++ programmer, so the user input part is kind of messed up.
hey here is a simple solution without using malloc,i did this when i was on the 0th level for c and had no idea about "alloc.h" functions,
You can have the square array having #rows = #cols = max(#rows,#cols),if we take your example then the matrix would be a 3x3 matrix,then add any special char in the blank entries,so the matrix will look like this
matrix:1 2 3
4 5 6
# # #
now you can easily convert the matrix in the way you want...
Bottom line:To make the matrix operations simpler try to convert them in square matrix...
One more thing using MALLOC is the best possible way ,this is just in case you are not handy with all those alloc.h function defs...
theoretically, you have two arrays
Array x and y
Int grades [x] [y]
you can swap these two arrays and you get
int grades [y] [x]
to do that there are many methods e.g. by copying the arrays to another two 1D, or one 2D Array, or simple Pointer Swap
i have problem with the third function (GetMatrix) the others are works.
i want to catch data from user into the matrix by poiters only
the lines:
typedef int pArr[COLS];
void GetMatrix(pArr* ,int , int );
M[ROWS][COLS];
are constraints
how i need to do the scan, i try to use scanf("%d",*(M+cols*i+j))
but i get error..its probably wrong
what is need to do to make it right
thx all
the code :
#pragma warning ( disable: 4996 )
#include <stdio.h>
#include <string.h>
#define ROWS 2
#define COLS 3
typedef int pArr[COLS];
void MergeStrings(char* str1,char* str2,char* strRes);
void StrReverse(char* strRes,char* strRev);
void GetMatrix(pArr* M ,int rows , int cols);
void main()
{
char str1[256],str2[256],strRes[256],strRev[256];
int M[ROWS][COLS];
printf("Please enter first string:\n");
flushall();
gets(str1);
printf("\nPlease enter second string:\n");
flushall();
gets(str2);
printf("\nMerge of: %s\n",str1);
printf("with: %s\n",str2);
MergeStrings(str1,str2,strRes);
StrReverse(strRes,strRev);
printf("is:\n");
printf("==> %s\n",strRes);
printf("\nthe reversed merged string is:\n");
printf("==> %s\n\n",strRev);
GetMatrix(M,ROWS,COLS);
}
void MergeStrings(char* str1,char* str2,char* strRes)
{
int i=0,j=0,a=0,flag=0,flag2=0;
do
{
while( *(str1+i)==' ')
i++;
while( *(str2+j)==' ')
j++;
while( *(str1+i)!=' ' && *(str1+i)!='\0')
{
*(strRes+a)=*(str1+i);
i++;
a++;
}
if(flag!=1)
{
*(strRes+a)=' ';
a++;
}
if(*(str1+i)=='\0')
flag=1;
while( *(str2+j)!=' ' && *(str2+j)!='\0')
{
*(strRes+a)=*(str2+j);
j++;
a++;
}
if(flag2!=1)
{
*(strRes+a)=' ';
a++;
}
if(*(str2+j)=='\0')
flag2=1;
}while( (*(str1+i)!='\0') || (*(str2+j)!='\0') );
*(strRes+a)='\0';
}
void StrReverse(char* strRes,char* strRev)
{
int size,i=0,j=0;
size=strlen(strRes);
for(i=size-2 ; i>=0 ;i--)
{
*(strRev+j)=*(strRes+i);
j++;
}
*(strRev+size-1)='\0';
}
void GetMatrix(pArr* M ,int rows , int cols )
{
}
do you mean?
int GetMatrix( pArr* M ,int rows , int cols )
{
return 1==scanf("%d",&M[rows][cols]);
}
#define ROWS 2
#define COLS 3
typedef int pArr[COLS];
void GetMatrix(pArr* M ,int rows , int cols )
{
for(int i = 0; i < rows; i++)
for(int j = 0; j < cols; j++)
scanf("%d", &(M[i][j]));
}
int main()
{
int M[ROWS][COLS] = {{100, 101, 102},{103, 104, 105}};
printf("before\n");
for(int i = 0; i < ROWS; i++){
for(int j = 0; j < COLS; j++)
printf("%d ", M[i][j]);
printf("\n");
}
printf("enter values\n");
GetMatrix(M, ROWS, COLS);
printf("after\n");
for(int i = 0; i < ROWS; i++){
for(int j = 0; j < COLS; j++)
printf("%d ", M[i][j]);
printf("\n");
}
}
Output:
before
100 101 102
103 104 105
enter values
0 1 2 3 4 5
after
0 1 2
3 4 5
Inside the function, M is a pointer to an array of three integers. M[i] is the i-th array, and M[i][j] is the j-th element in the i-th array. & operator gives its address to the scanf, which happily stores the read number in there.
Here is what happens when you replace scanf("%d", &(M[i][j])); with scanf("%d",*(M+cols*i+j)):
for(int i = 0; i < rows; i++)
for(int j = 0; j < cols; j++)
scanf("%d", *(M + cols * i + j));
snip..
before
100 101 102
103 104 105
enter values
0 1 2 3 4 5
after
0 101 102
1 104 105
In the first iteration of the inner loop, i and j are zero, and *(M+cols*i+j) becomes *M. Since M is a pointer to an array, dereferencing it gives you an array of integers which decays into pointer to an integer. Thus the first number get stored at the correct place.
In the second iteration of the inner loop, j is 1. Thus, it is *(M + 1). Pointer arithmetic comes into picture here. Since M is a pointer to an array of three integers, (M + 1) is a pointer to an array of three integers that points to the second array; dereferencing it gives the array, which decays into pointer and scanf writes the second number there.
In the third iteration, j is 2 and (M + 2) points to the third (non existent) array and scanf writes the entered number into that memory location in the stack, thus corrupting the stack.
So on and so forth. It attempts to write into every third integer location, leaving our preinitialized values (101, 102, 104, 105) untouched.
If you want to it with pointers, you can cast M as a pointer to int as in:
scanf("%d", (int*)M + cols * i + j);
Once you cast M as int*, pointer arithmetic adds 1 * sizeof(int) to the starting position instead of 1 * sizeof(array of three ints), thus giving the desired results.
Update - answer to the comment I received in Facebook.
Consider the snippet:
int a = 10;
scanf("%d", &a);
printf("%d", a);
Scanf stores the entered value at the specified address - hence we pass a pointer to int as its argument. printf prints the passed value - hence we pass an int as the argument. The same difference applies here. ((int*)M + cols * i + j) is of type int*, pointer to an integer. To print the integer at that location we should dereference it using * operator. Thus it becomes:
printf("%d\t",*((int*)M + cols * i + j));
Oh, and by the way, you'd have received a faster reply if you had posted your doubts here itself instead of my FB. There are lots of good people ready to help hanging out in SO - and I check FB only on weekends.