Using pointers instead of an array [closed] - c

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I wrote this program a few weeks ago using arrays and now I need to use pointers instead of using arrays. I'm not exactly sure how to go about doing that so any tips would be appreciated! Thanks! :D
Here is the code:
#include <stdio.h>
int showArray(int row);
int exchangeRow(int row1, int row2);
int x, y;
int array[10][10];
int j;
int k;
int inputrow;
int inputcolumn;
int scanrow;
int temp;
int row1;
int row2;
int main() {
// Initialize array
for(j = 0; j < 10; j++) {
printf("\n");
for(k = 0; k < 10; k++) {
array[j][k] = j * 10 + k;
printf("%d ", array[j][k]);
}
}
printf("\n \n");
// Print out selected row
printf("Type in a number for the corresponding row to be printed \n");
scanf("%d", &inputrow);
if(inputrow >= 0 && inputrow < 10) {
for(j = 0; j < 10; j++) {
printf("%d ", array[inputrow][j]);
}
}
printf("\n \n");
//Print out selected column
printf("Type in a number for the corresponding column to be printed \n");
scanf("%d", &inputcolumn);
if(inputcolumn >= 0 && inputcolumn < 10) {
for(j = 0; j < 10; j++) {
printf("%d ", array[j][inputcolumn]);
}
}
printf("\n \n");
printf("Type in a number for the row that method showArray will print \n");
scanf("%d", &scanrow);
showArray(scanrow);
printf("\n \n");
printf("Type in two numbers for the rows that method exchangeRow will switch \n");
scanf("%d %d", &row1, &row2);
exchangeRow(row1, row2);
printf("\n \n");
system("PAUSE");
}
int showArray(int row) {
for(j = 0; j < 10; j++) {
printf("%d ", array[row][j]);
}
}
int exchangeRow(int row1, int row2) {
if(row1 >= 0 && row1 < 10 && row2 >= 0 && row2 < 10) {
temp = row1;
row1 = row2;
row2 = temp;
printf("The first row now holds the values: ");
showArray(row1);
printf("\n");
printf("The second row now holds the values: ");
showArray(row2);
}
}

I take it you mean "using dynamic memory allocation"...
The way a lot of people do 2D arrays dynamically is like this:
const size_t nrows = 10, ncols = 10;
int **array = malloc( nrows * sizeof(int*) );
for( i = 0; i < nrows; i++ ) {
array[i] = malloc( ncols * sizeof(int) );
}
But I hate this. If you are doing production code, this can be very slow. It's also harder to handle the case where you run out of memory, and there's no guaranteed locality of your array. Plus, it's ugly to free:
for( i = 0; i < nrows; i++ ) free(array[i]);
free(array);
In memory, your static array[10][10] is one contiguous block. So you should do the same:
int **array = malloc( nrows * sizeof(int*) );
array[0] = malloc( nrows * ncols * sizeof(int) );
for( i = 1; i < nrows; i++ ) {
array[i] = array[i-1] + ncols;
}
To free that:
free(array[0]);
free(array);
I often take this a step further, and do a single memory allocation instead of two. That way I have just one pointer. But I won't do that here. You have to be a little conscious of alignment, and the code is a little messier. It's an optimization that usually you don't need.
Hope that helps.

To be more specific, what is required of you is to use pointer notation instead of array notaiton
This would probably mean that your 2 dimensional array should be allocated as an array of pointers. Also it's individual elements should be accessed using pointers rather than the usual array indexing.
For e.g.
int * a = malloc(10 * sizeof(int)); // allocate memory for 10 integers
*a = 1; // assign first element of array
*(a+1) = 2; // assign second
The above was for 1D array. Extend it to multiple dimensions as in your original program.

When you declare an array, such as int arr[4];, arr actually "points" to a location in memory with 4 "spaces" that holds an integer each.
&arr means "address of" arr.
So, a pointer to arr could be defined as:
int *ptr = &arr[0];
But how would you get the data that ptr points to? The answer is:
*ptr;
But, this will only show you the first value of the data stored in the first "space" that arr occupies. To get the others in the array, all you need to do is increment your pointer along the space in memory, like so:
ptr++;
Further information can be found here: http://alumni.cs.ucr.edu/~pdiloren/C++_Pointers/neighbor.htm

Related

Dynamic Memory in C [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I can't understand what doing the row
*(m[i] + sizes[i] - 1) = n;
#include <stdio.h>
#include <stdlib.h>
#define MAXSTR 100
int main()
{
int i, j, k, n;
char str[MAXSTR];
printf("Enter amount of rows: ");
fgets(str, MAXSTR, stdin);
k = atoi(str);
int* sizes = (int * ) calloc(k, sizeof(int));
int* sum = (int * ) calloc(k, sizeof(int));
int** m = (int ** ) calloc(k, sizeof(int * ));
printf("Enter matrix:\n");
for (i = 0; i < k; i++)
{
fgets(str, MAXSTR, stdin);
char* sym = str;
while (1)
{
m[i] = (int * ) realloc(m[i], (++sizes[i]) * sizeof(int));
n = strtol(sym, & sym, 10);
sum[i] += n;
if (n)
{
*(m[i] + sizes[i] - 1) = n;
}
else
{
--sizes[i];
break;
}
}
}
printf("\nMatrix: \n");
for (i = 0; i < k; i++)
{
for (j = 0; j < sizes[i]; j++)
printf("%i ", *(m[i] + j));
printf("\n");
}
printf("\nSum of elements of row:\n");
for (i = 0; i < k; i++)
printf("#%i - %i\n", i + 1, sum[i]);
free(sizes);
free(sum);
free(m);
return 0;
m is the matrix. Or more formally, it appears to be an array of "rows". Where each row is an array of integers.
sizes[i] is the length of the row represented by m[i].
This expression
*(m[i] + sizes[i] - 1) = n;
Appears to assign the value n to the last index of the row identified by m[i]. Essentially, it's appending to the end of the reallocated array.
This entire block of code is a bit complex:
while (1)
{
m[i] = (int * ) realloc(m[i], (++sizes[i]) * sizeof(int));
n = strtol(sym, & sym, 10);
sum[i] += n;
if (n)
{
*(m[i] + sizes[i] - 1) = n;
}
else
{
--sizes[i];
break;
}
}
It could be simplified to just:
int rowsize = 0;
while (1)
{
n = strtol(sym, &sym, 10); // parse the next number in str
if (n == 0) // the row ends when 0 is read
{
break;
}
m[i] = (int *)realloc(m[i], (rowsize+1) * sizeof(int); // grow the row's size by 1
m[i][rowsize] = n;
sum[i] += n;
rowsize++;
}
sizes[i] = rowsize;
m[i] is a pointer to the first element in the i:th matrix row
sizes[i] is the current number of columns in row i
sizes[i] - 1 is the last element in row i
m[i] + sizes[i] - 1 is a pointer to the last element in row i
*(m[i] + sizes[i] - 1) is the last element in row i
When allocating memory in C the result should not be cast, so
int* sizes = (int * ) calloc(k, sizeof(int));
should be simply
int* sizes = calloc(k, sizeof(int));
Also, the rows of the matrix m are never freed; to free the entire matrix you would need
for (i = 0; i < k; i++) {
free(m[i]);
}
free(m);
To answer your question the statement *(m[i] + sizes[i] - 1) = n; assigns the value n to whatever m[i] + sizes[i] - 1 points to. m is a pointer to a pointer to an int, so m[i] is an address of an int pointer. sizes[i] - 1 is usually how you convert from a size to index, so it's an offset from that int pointer.
Here are some suggested changes (all but one implemented below):
Reduce variable scope but initialize sum to NULL before the first failure so it can be unconditionally deallocated
It is better user experience to just read the data and terminate with an empty line instead of asking for the user count upfront. Just update the count k as we go along. This eliminates atoi which does not do any error handling. If you want to crash the program due to being out of memory you have to provide the data not just large a count.
(not fixed) realloc of 1 element at a time, if the O(i^2) is a performance issue, keep track of size and capacity of sum. When size == capacity, realloc by some factor, say, 2. Optionally, realloc to size when when we finish reading data as we now have the actual number of lines k.
No point of printing the array you just entered, which means we can get rid of the m and sizes arrays
Deallocate sum if realloc fails by introducing a temporary sum2 variable that will be NULL on error, but sum will still point to previously allocated data
Check for under and overflow of n and sum
Use sizeof on variable instead of type so you can change type just one place if needed
Allow 0 values by passing in by using a separate pointer endptr than sym to strtol()
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#define CHECK(p, msg) if(!(p)) {\
printf("%s:%d %s\n", __FILE__, __LINE__, (msg));\
goto out;\
}
#define MAXSTR 100
int main() {
int k;
char str[MAXSTR];
int *sum = NULL;
printf("Enter matrix:\n");
for(int i = 0;; i++) {
fgets(str, MAXSTR, stdin);
char *sym = str;
int *sum2 = realloc(sum, (i + 1) * sizeof(*sum));
CHECK(sum2, "realloc failed");
sum = sum2;
int j;
for(j = 0;; j++) {
char *endptr;
long n = strtol(sym, &endptr, 10);
CHECK(n >= INT_MIN && n <= INT_MAX,\
"value truncated");
if(sym == endptr) {
break;
}
sym = endptr;
CHECK((n >= 0 && sum[i] <= INT_MAX - n) || \
(n < 0 && sum[i] >= INT_MIN - n),\
"sum truncated");
sum[i] += n;
}
if(!j) {
k = i;
break;
}
}
printf("Sum of elements of row:\n");
for (int i = 0; i < k; i++)
printf("#%i - %i\n", i + 1, sum[i]);
out:
free(sum);
return 0;
}
Example execution:
Enter matrix:
0 1 2
Sum of elements of row:
#1 - 3

C - create 3D array of ints and initialize it to zeros

I'm trying to create a 3D array of ints initialized to zeros each of fixed size denoted as "dim".
For example, for dim=3, it will have 27 cells for ints.
I tried this:
int ***board;
int **rows;
int *tried;
board = calloc(dim,sizeof(int**));
rows = calloc(dim*dim, sizeof(int*));
tried = calloc(dim*dim*dim, sizeof(int));
int i;
int j;
int k;
for (i=0 ; i<dim ; i++) {
board[i] = rows + i*dim*dim;
for (j=0 ; j<dim ; j++) {
board[i][j] = tried + j*dim + i*dim*dim;
}
}
for (i=0 ; i<dim ; i++) {
for (j=0 ; j<dim ; j++) {
for (k=0 ; k<dim ; k++) {
board[i][j][k] = 0;
}
}
}
Trying to debug it, I found that it works until:
board[1][1][0] = 0
And then the program gets stuck and i just can't find the reason.
Can someone explain this please?
Thanks!
First about the error in your code. Compare this:
rows = calloc(dim*dim, sizeof(int*));
to this:
for (i=0 ; i<dim ; i++) {
board[i] = rows + i*dim*dim;
The entire size of the array allocated to rows is dim*dim elements. So, already in the second iteration of this loop, you access it out of bounds. You probably meant:
for (i=0 ; i<dim ; i++) {
board[i] = rows + i*dim;
As I already mentioned in the comment, this is not a 3D array. It mimics the usage in code by using pointers and you're using a kind-of clever trick here, so you only need 3 allocations in total. This might be a good idea under the following conditions:
your dim is variable at runtime, so you can't know it in advance, and
you have to write code for compilers that don't support VLAs1) (variable-length-arrays).
If one of this conditions is not true, it's much better to use a real 3D array. If the array doesn't have to live after leaving your function and the size isn't huge, just use a simple variable with automatic storage duration like
int board[3][3][3] = { 0 }; // possibly #define the dimension
or, for a variable dim, requiring a compiler supporting VLAs
int board[dim][dim][dim] = { 0 };
If on the other hand, the array will be huge and/or you need to return it from your function, you indeed have to allocate it dynamically. Then just use the following:
int (*board)[3][3] = calloc(3, sizeof *board); // static size
int (*board)[dim][dim] = calloc(dim, sizeof *board); // dynamic case, with VLA suppport
Also note that calloc() already sets your allocated memory to 0, so no need for looping all over it.
Side notes:
with sizeof, prefer the expression form, so instead of writing
int *a = calloc(5, sizeof(int));
better write
int *a = calloc(5, sizeof *a);
this avoids errors when you later change the type of a.
always check the return value of malloc() and friends -- they might return a null pointer (e.g. when you're running out of memory).
1) VLAs don't exist in the oldest standards C89/C90 -- they were introduced in C99 as a mandatory feature, but later made optional in C11. This allows C11 compilers to omit them, which might make sense when e.g. targeting embedded systems. In practice, you can safely assume a C11 compliant compiler supports them if it isn't special purpose.
I rewrote your code to show how allocation of a 3D array could look like. And as pointed out in the comments, there's no need to initialize the array to 0 since calloc does that for you. Had you used malloc the array would not have been initialized.
#include <stdlib.h>
#include <stdio.h>
#define dim (3u)
int main() {
int x;
int y;
int z;
int ***cube;
cube = calloc(dim, sizeof(int**));
for (z = 0; z < dim; z++) {
cube[z] = calloc(dim, sizeof(int*));
for (y = 0; y < dim; y++) {
cube[z][y] = calloc(dim, sizeof(int));
}
}
for (z = 0; z < dim; z++) {
for (y = 0; y < dim; y++) {
for (x = 0; x < dim; x++) {
cube[z][y][x] = z + y + x;
}
}
}
for (z = 0; z < dim; z++) {
for (y = 0; y < dim; y++) {
for (x = 0; x < dim; x++) {
printf("%d ", cube[z][y][x]);
}
printf("\n");
}
printf("\n");
}
return 0;
}
What you want to store in it is up to you, in my example I wrote the sum of the counter to each index.
Code below is Unlicense.
I will suggest something different. Just create a 1D array and set some boundaries to interpret it as 3D. I added some test cases for you to better visualize how it works. Do not forget to look at how easy 'calloc' call is. Here is the code:
#include <stdlib.h>
#include <stdio.h>
int getindex(int dim, int x, int y, int z) {
return z * dim * dim + y * dim + x;
}
void printarray(int* tdarray, int dim) {
printf("[\n");
for (int i = 0; i < dim; i++) {
printf("\t[\n");
for (int j = 0; j < dim; j++) {
printf("\t\t[");
for (int k = 0; k < dim; k++) {
if (k == 0) printf("%d", *(tdarray + getindex(dim, k, j, i)));
else printf(",\t %d", *(tdarray + getindex(dim, k, j, i)));
}
printf("]\n");
}
printf("\n\t]\n");
}
printf("]\n");
}
int main() {
int dim = 10;
size_t arraysize = sizeof (int) * dim * dim * dim;
int lookupindex = getindex(dim, 7, 5, 4); /* Numbers picked randomly */
int* tdarray = (int*) malloc(arraysize);
calloc(*tdarray, arraysize);
/* Below is test code and visualizations, all magic happens above.*/
if (*(tdarray + lookupindex) == 0) *(tdarray + lookupindex) = 7;
printf("tdarray[x:%d, y:%d, z:%d]:\t%d\n\n", 7, 5, 4, *(tdarray + lookupindex));
printarray(tdarray, dim);
printf("\n\n\n\n\n\n\n\n\n\n");
for (int i = 0; i < getindex(dim, 9, 9, 9) + 1; i++) *(tdarray + i) = i;
printarray(tdarray, dim);
free(tdarray);
}

Getting size of array in one line with the input [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I've been trying to create a dynamic 2d matrix where the user gives me the size of the matrix along with the input.
For example: 3 1 2 3 4 5 6 7 8 9, where the first int 3 is the size of the matrix (3*3) and the rest of the numbers are the numbers I'd like to input in my matrix.
Any ideas how to do it?
If "dynamic" just means that the size of the 2d-matrix is defined at runtime, then you might use a variable length array. These are created in function scope and are "real" 2D-arrays in the sense that they are n x n continuously stored integers that can be accessed like array[x][y]. See the following code illustrating this approach:
int main() {
int n;
if (scanf("%d", &n) != 1 || n <= 0) {
printf("invalid input.");
return 1;
}
int array[n][n]; // variable length array
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (scanf("%d", &array[i][j]) != 1) {
printf("invalid input.");
return 1;
}
}
}
// matrix is available in main...
return 0;
}
If "dynamic" means, however, allocated dynamically using malloc, then you have two chances, both not leading to a "real" 2D-array:
First, (dynamically) create an array of pointers, each entry pointing to a (dynamically) allocated array of ints. Advantage: you can access it like arr[x][y]; Drawback: rows are not continguously stored but (probably) spread in memory.
Second, (dynamically) create an array of ints of size n * n; Advantage: values are stored in a continguous block of memory; drawback: you cannot access it like arr[x][y] but rather have to calculate the cell's position on your own, i.e. arr[y * n + x];
This is what you are looking for.
The code is explained in the comments in the code.
Read here, how to make dynamic 2d array in c.
#include<stdio.h>
#include<stdlib.h>
int main()
{
int n;
scanf("%d", &n);
/* It will allocate an array of pointers with n elements*/
int **arr = (int**)malloc(n*sizeof(int*));
/* each element in the above array would contain another array that makes the upper array as the 2D array */
for (int i = 0; i < n; i++)
arr[i] = (int*)malloc(n * sizeof(int));
/*It is taking the input to put inside the array */
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
scanf("%d", &arr[i][j]);
/* This is printing the content inside the array */
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
printf("%d\t", arr[i][j]);
return 0;
}

2D array as contiguous block of memory

I know this question was answered but it somehow doesn't work for me.
I dynamically allocate memory for array like this:
arr = (int**)(malloc(rows*sizeof(int*)));
arr[0] = (int*)(malloc(rows*columns*sizeof(int))); // <-- THIS DOESN'T WORK
printf("\nArray: \n");
while(fscanf(fp, "%d", &num) == 1) {
//arr[row] = (int*)(malloc(columns*sizeof(int))); <---THIS WORKS
arr[row][col] = num;
printf("%d ", arr[row][col]);
if((++col == columns)){
row++;
col = 0;
printf("\n");
}
}
It throws segmentation fault after 4th row, if matrix is 6x6.
Any advice? Thanks
EDIT:
See: http://www.geeksforgeeks.org/dynamically-allocate-2d-array-c/ point number 4. If I do it like in point 3, it works. But I need it like in 4.
There exists no case where you should use fragmented malloc calls like you do. It is wide-spread but bad and incorrect practice. As you point out, it will not give you a true 2D array in adjacent memory, but rather a fragmented, slow mess.
How to do this properly:
In standard C, write
int (*arr)[rows][columns] = malloc (sizeof(*arr));
(*arr)[r][c] = something;
...
free(arr);
or if you prefer to use syntax which is easier-to-read (but perhaps harder to understand):
int (*arr)[columns] = malloc (sizeof(int[rows][columns]));
arr[r][c] = something;
...
free(arr);
In obsolete versions of C, you will have to write a "mangled array":
int* arr = malloc(rows * columns * sizeof(*arr));
arr[r*c] = something;
...
free(arr);
To allocate a contiguous memory, you'll have to use
arr = malloc(sizeof(int *) * rows);
arrayData = malloc(sizeof(int) * columns * rows);
for(i = 0; i < rows; i++)
arr[i] = arrayData + i * columns ;
To deallocate you'll need to have
free( arrData );
free( arr );
See here
You need to allocate memory for each row, not just the first row. Replace
arr[0] = (int*)(malloc(rows*columns*sizeof(int)));
with
for(int i = 0; i < rows; i++)
arr[i] = malloc(columns * sizeof(int));
The changes made here are:
All the rows will be allocated columns * sizeof(int) bytes of memory.
Casting the result of malloc is pointless in C. I've removed it.
You might need to add a check in the loop to prevent an overflow. Something like
if(row == rows)
{
puts("Matrix full; Exiting loop...");
break;
}
The fixed code would be
int i, row = 0, col = 0;
int rows = 6, columns = 6; /* For 6x6 matrix */
arr = malloc(rows * sizeof(int*));
for(i = 0; i < rows; i++)
arr[i] = malloc(columns * sizeof(int));
printf("\nArray: \n");
while(fscanf(fp, "%d", &num) == 1) {
arr[row][col] = num;
printf("%d ", arr[row][col]);
if(++col == columns){
row++;
col = 0;
printf("\n");
}
if(row == rows)
{
puts("Matrix full; Exiting loop...");
break;
}
}
For a 6x6 matrix, dynamic memory is overkill. You should simply use:
int arr[rows][cols];
This is much simpler, cleaner, quicker, less error prone and generally all round safer — as long as you keep the matrix size small enough that it easily fits on the stack. If you need a large matrix (say from 1 MiB upwards, but you'll need to tune your threshold to suit your systems), then dynamic memory is relevant.
You can make the single allocation to arr[0] work, but you have to do explicit assignments to each of arr[1] through arr[5]. I did it this way:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int rows = 6;
int cols = 6;
int **arr = (int**)(malloc(rows*sizeof(int*)));
arr[0] = (int*)(malloc(rows*cols*sizeof(int)));
for (int i = 1; i < rows; i++)
arr[i] = arr[i-1] + cols;
printf("\nArray: \n");
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
arr[i][j] = (i+1) * (cols + 1 - j);
}
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
printf("%3d", arr[i][j]);
putchar('\n');
}
free(arr[0]);
free(arr);
return(0);
}
Sample output:
Array:
7 6 5 4 3 2
14 12 10 8 6 4
21 18 15 12 9 6
28 24 20 16 12 8
35 30 25 20 15 10
42 36 30 24 18 12
Running valgrind gives a clean bill of health.

Addition Of Pointers in C [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
Please go through the following loops:
I am especially confused about the first loop,
1st loop:
for(i = 0; i < n; i++)
{
scanf("%d", ptr + i);
}
for(i = 0; i < n; i++)
{
sum = sum + (*(ptr + i));
}
2nd loop:
int *x ;
for(i = 0; i < n; i++)
{
x = ptr + sizeof(i);
scanf("%d",x );
}
for(i = 0; i < n; i++)
{
x = ptr + sizeof(i) ;
sum = sum + (*x);
}
Why do entering the elements in the array by using malloc
using the above loops give the same result ?
Why are the first and second loop giving equal or right result ?
why are (ptr + i) and ptr + sizeof(i) working in same waY?
Entire program is
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#define NULL 0
int main()
{
int *ptr;
int i, n, sum = 0 ;
float avg ;
printf("Enter the number of elements you want to store in the array.");
scanf("%d", &n);
ptr = (int *) malloc( n * sizeof(int)) ; /*Dynamic Memory allocation*/
if(ptr == NULL)
{
printf("The required amount of memory is not available. ");
getch();
exit(0);
}
else
{
printf("Enter the elements\n");
for(i = 0; i < n; i++)
{
scanf("%d", ptr + i);
}
for(i = 0; i < n; i++)
{
sum = sum + (*(ptr + i));
}
printf("\nThe sum of %d elements entered is = %d",n , sum );
avg = sum / n ;
printf("\nThe average of %d number of the array is %f", n, avg);
}
printf("\n");
getch();
}
why are (ptr + i) and ptr + sizeof(i) working in same waY?
They are not. In the first example, you read n values into an array (storing them in succesive elements), and then add those n values. In the second example, you read n values and store them all in the same element of the array (overwriting the previous element), so you end up with an array that is mostly uninitialized, but has one element set to the last value read. You then add that element to itself n times.
So you might end up with the same sum in both cases (for example, if your numbers are 1,3,2), or you might not.

Resources