Pointer to Pointer to integer - c

i'm using a pointer to pointer to intger as a 2 Dims array, i wrote these code but i failed on getting the integer value.
#include<stdio.h>
#include<conio.h>
void main(void)
{
int **pptr = 0, size = 0, size2 = 0, i, j;
clrscr();
printf("Enter Size of Main Store n");
scanf("%d", &size);
pptr = (int **) malloc(size * sizeof(int *));
printf("Enter Size of Sub Store n");
scanf("%d", &size2);
for (i = 0; i < size; i++) {
pptr[i] = (int *) malloc(size2 * sizeof(int));
}
printf("Enter Values n");
for (i = 0; i < size; i++) {
for (j = 0; j < size2; j++) {
scanf("%dn", pptr[i][j]);
}
}
clrscr();
printf(" Valuesn");
for (i = 0; i < size2; i++, pptr++) {
printf("%dn", *pptr + i);
}
getch();
}
it prints rubbish!!

scanf("%d", arg) expects a pointer to int, but
for (i = 0; i < size; i++) {
for (j = 0; j < size2; j++) {
scanf("%dn", pptr[i][j]);
}
}
you pass it an int, an uninitialised int at that. The indeterminate value in that memory location is then interpreted as a pointer, and the scan tries to store the converted value who-knows-where. It is not unlikely that that will cause a segmentation fault.
You should pass &pptr[i][j] as the argument there.
for (i = 0; i < size2; i++, pptr++) {
printf("%dn", *pptr + i);
}
prints the int* *pptr +i, which is &pptr[0][i], using the %d format that expects an int argument.
You should
printf("%d\n", pptr[0][i]);
if you want to print the values of the diagonal (as seems to be the case, since you also increment pptr in the loop), or, better
for(i = 0; i < size && i < size2; ++i) {
printf("%d\n", pptr[i][i]);
}
or, if you want to print the entire grid,
for(i = 0; i < size; ++i) {
for(j = 0; j < size2; ++j) {
printf("%d ", pptr[i][j]);
}
printf("\n");
}

scanf takes a int *, not an int. So...
scanf("%dn", pptr[i][j]);
should be:
scanf("%dn", &(pptr[i][j]));
or it could be:
scanf("%dn", (pptr[i]+j));
also, printf needs a value (int), not a pointer. So...
printf("%dn", *pptr + i);
should probably be something like:
printf("%dn", *(*pptr+i));
or the much nicer looking equivalent:
printf("%dn", pptr[0][i]);

Related

deferencing the int malloc pointer

int main()
{
/* Enter your code here. Read input from STDIN. Print output to STDOUT */
int rslt, n;
float sum = 0;
scanf("%d", &n);
int *tri = (int*)malloc(n * 3 * sizeof(int));
if(tri == NULL){
return 1;
}
printf("%d\n", *(tri[0]));
when I am referencing the tri pointer then it is showing the error.
invalid type argument of unary '*'.
thanks for the answer.
The above part is clarified but I have another issue. but I have another issue
int main()
{
int rslt, n;
float sum = 0;
scanf("%d", &n);
int *tri = (int*)malloc(n * 3 * sizeof(int));
if(tri == NULL){
return 1;
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3; j++)
{
scanf("%d", &(tri[j]));
}
printf("\n");
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3; j++)
{
sum += tri[j] / 2;
printf("%d %d\n",sum,tri[j] / 2);
}
}
printf("%d\n",sum);
return 0;
}
when I am printing the tri[j] it is showing some garbage value.
The variable tri has the type int * due to this declaration
int *tri = (int*)malloc(n * 3 * sizeof(int));
Pay attention to that you allocated an uninitialized memory.
The expression tri[0] has the type int. And you are trying to apply the dereference operator to the expression of the type int
*(tri[0])
So the compiler issues an error.
Instead you could write
int *tri = (int*)calloc(1, n * 3 * sizeof(int));
and then write either
printf("%d\n", tri[0]);
or
printf("%d\n", *tri);
These for loops
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3; j++)
{
scanf("%d", &(tri[j]));
}
printf("\n");
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3; j++)
{
sum += tri[j] / 2;
printf("%d %d\n",sum, tri[j] / 2);
}
}
printf("%d\n",sum);
are incorrect. There are used an incorrect conversion specifier %d instead of %f with the variable sum and incorrect expressions for indices. You need to write
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3; j++)
{
scanf("%d", &(tri[3 * i + j]));
}
printf("\n");
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < 3; j++)
{
sum += tri[3 * i + j] / 2;
printf("%f %d\n",sum, tri[3 * i + j] / 2);
}
}
printf("%f\n",sum);
The array expression a[i] is defined as *(a + i) - given some address value a, offset i elements (not bytes!) from that address and dereference the result, so
*tri == *(tri + 0) == tri[0]
The expression tri[0] has type int, which is why the compiler is complaining when you write *(tri[0]); the operand of the unary * operator must have a pointer type.
So in your printf statement you would use either *tri or tri[0]. The type of either expression is int.
As others have said, malloc does not initialize the allocated memory, so the value of tri[0] may be anything. You could use calloc instead, which initializes the memory to all-bits-zero:
int *tri = calloc( n, sizeof *tri );
In C you do not need to cast the result of malloc, calloc, and realloc1, and most of us will advise you to not do so. Similarly, since the type of the expression *tri is int, the result of sizeof *tri is the same as sizeof (int). This way you don't have to worry about keeping types straight between the declaration, the cast, and the sizeof expression, so you're less likely to make a mistake.
This is not the case in C++, but if you're writing C++ you shouldn't be using the C *alloc functions anyway.

How to pass and return two-dimensional array from function in c

I am relatively new to c, and I still have not been able to find a good way of passing and returning a multi-dimensional array from a function. I found the following code, however it doesn't seem like a good way to do things because it passes the array and then to use it, it creates a duplicate with the malloc function. Is there a way to do it without the copying and malloc function, or a better way to pass and return an 2d array from a function in c in general? Thanks.
#include <stdio.h>
#include <stdlib.h>
int **matrix_sum(int matrix1[][3], int matrix2[][3]){
int i, j;
int **matrix3;
matrix3 = malloc(sizeof(int*) * 3);
for(i = 0; i < 3; i++) {
matrix3[i] = malloc(sizeof(int*) * 3);
}
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
matrix3[i][j] = matrix1[i][j] + matrix2[i][j];
}
}
return matrix3;
}
int main(){
int x[3][3], y[3][3];
int **a;
int i,j;
printf("Enter the matrix1: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&x[i][j]);
}
}
printf("Enter the matrix2: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&y[i][j]);
}
}
a = matrix_sum(x,y); //asigning
printf("The sum of the matrix is: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
printf("%d",a[i][j]);
printf("\t");
}
printf("\n");
}
//free the memory
for(i = 0; i < 3; i++) {
free(a[i]);
}
free(a);
return 0;
}
The array are not copied for agurments. Just pointers to the first elements of them (int[3]) are passed.
To avoid malloc(), you should add another argument to specify the array where the result should be stored.
#include <stdio.h>
void matrix_sum(int matrix3[][3], int matrix1[][3], int matrix2[][3]){
int i, j;
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
matrix3[i][j] = matrix1[i][j] + matrix2[i][j];
}
}
}
int main(){
int x[3][3], y[3][3], a[3][3];
int i,j;
printf("Enter the matrix1: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&x[i][j]);
}
}
printf("Enter the matrix2: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
scanf("%d",&y[i][j]);
}
}
matrix_sum(a,x,y);
printf("The sum of the matrix is: \n");
for(i = 0; i < 3; i++){
for(j = 0; j < 3; j++){
printf("%d",a[i][j]);
printf("\t");
}
printf("\n");
}
return 0;
}
An array can be declared and used through a reference (pointer)
for instance
char array[] = {'h','e','l', 'l', 'o', '\0'};
char *pointer = array;
the way pointers work can be understood by calling sizeof() on a given type
printf("char:%d\nchar_pointer: %d\n", sizeof(char), sizeof(char*));
which results in the following output.
char:1
char_pointer: 4
these results mean that even though a char has 1byte, its pointer needs 4 in order to be stored in memory thus, they are not the same type.
now in order to pass an array as an argument to a function you have many options
void function1(array[4])
{
//this function can receive an array of four elements and only four elements;
//these types of functions are useful if the algorithm inside the function only works
//with a given size. e.g. matrix multiplication
}
//or
void function2(char array[], int size)
{
//this function can receive an array of elements of unknown size, but you can
//circumvent this by also giving the second argument, the size.
int i;
for(i = 0; i <= size; i++)
{
printf("%c", array[i]);
}
}
In order to use or call any of these functions you could pass the array or a pointer to the array
function2(array, 5);
function2(pointer, 5);
//these results are the same
The same applies to a multidimensional array
void function3(char** multi_dim_array, array_size_first_dim, array_size_second_dim);
//and you can call it by using the same syntax as before;
void main(int argc, char[] argv*)
{
char** multi_dim = malloc(sizeof(char*) * 3);
int i;
for(i = 0; i<=3 ; i++)
{
multi_dim[i] = malloc(sizeof(char) * 4);
}
function3(multi_dim, 3,4);
}
if you want to return a multidimensional array you can just return a pointer
char **malloc_2d_array(int dim1, int dim2)
{
char ** array = malloc(sizeof(char*)*dim1);
int i;
for(i = 0; i<=dim2; i++)
{
array[i] = malloc(sizeof(char) * dim2);
}
return array;
}
as a final note, the reason the code you found, copies the array, is because of functional programming(a way of programming if you will) where a function call cant modify its input, thus it will always create a new value;
First of all this is not gonna be a technical explanation. I am just gonna try and explain what works not why.
For passing a multidimensional array you can use either an array with a defined size as you did in your example code:
void matrix_sum(int matrix3[][3])
Or if you don't want to use a defined size and want to take care of memory usage you can use a pointer to a pointer. For this case you also need to pass the size (unless you are passing NULL-terminated strings). Like this:
void matrix_sum(int **matrix, int size)
BUT for this case you can't call the function with a "normal" array. You need to use a pointer to a pointer or a pointer to an array.
int **matrix;
// make sure to allocate enough memory for this before initializing.
or:
int *matrix[];
For returning an array you can just return a pointer to a pointer like you did in your code example.
But you don't need to return an array, because if you change a value in an array, (in a different function) the value will stay changed in every other function.
A short example for this:
#include <stdio.h>
void put_zeros(int matrix[][3])
{
int i;
int j;
i = 0;
while (i < 3)
{
j = 0;
while (j < 3)
{
matrix[i][j] = 0;
j++;
}
i++;
}
}
void print_matrix(int matrix[][3])
{
int i;
int j;
i = 0;
while (i < 3)
{
j = 0;
while (j < 3)
{
printf("%d ", matrix[i][j]);
j++;
}
printf("\n");
i++;
}
}
int main(void)
{
int matrix_first[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
print_matrix(matrix_first);
put_zeros(matrix_first);
print_matrix(matrix_first);
}
This will print "1 2 3 4 5 6 7 8 9" because that's the first value we assigned.
After calling put_zeros it will contain and print "0 0 0 0 0 0 0 0 0" without the put_zeros returning the array.
1 2 3
4 5 6
7 8 9
0 0 0
0 0 0
0 0 0

initialization of arrays while operating with mallocs

Given the following piece of code, I don't understand why do we have to initialize every single row of the matrix when we have already created enough space in the stack.
#include <stdio.h>
#include <stdlib.h>
main() {
int **w;
int i, j;
int m, n;
printf("Number of rows in the matrix: ");
scanf("%d", &m);
printf("Number of columns in the matrix: ");
scanf("%d", &n);
w = (int **)malloc(m * n * sizeof(int));
for (i = 0; i < m; i++)
w[i] = (int *)malloc(n * sizeof(int));
for (i = 0; i < m; i++)
for (j = 0; j < n; j++) {
printf("Element [%d][%d]: ", i + 1, j + 1);
scanf("%d", &w[i][j]);
}
for (i = 0; i < m; i++)
for (j = 0; j < n; j++)
printf("Element [%d][%d]: %d\n", i + 1, j + 1, w[i][j]);
}
There are many issues in your code:
space is not allocated on the stack, but from the heap.
in both cases, memory allocated for the objects is uninitialized, which means it is not initialized to anything in particular and can have any value whatsoever. Relying on any particular contents is undefined behavior.
the matrix dimensions and all the matrix elements are read from standard input with scanf(). Yet you do not check for scanf() failure to convert integers from the characters read from stdin, so any invalid or missing input is going to cause undefined behavior at some point in the program.
your matrix is actually structured as an array of pointers to arrays of int, which is fine, but inconsistent with the size arguments used to allocate the first array: w = (int **)malloc(m * n * sizeof(int)); should be
w = malloc(m * sizeof(*w));
you could easily get objects pre-initialized to 0 by using calloc() instead of malloc():
for (i = 0; i < m; i++)
w[i] = calloc(n, sizeof(int));
you should also check for malloc() failure and exit with an appropriate diagnostic message.
main() is an obsolete prototype for the main function. You should either use int main(), int main(void) or int main(int argc, char *argv[])...
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
int get_int(void) {
int n;
if (scanf("%d", &n) != 1) {
printf("invalid input\n");
exit(EXIT_FAILURE);
}
return n;
}
void xalloc(size_t size) {
void *p = calloc(size, 1);
if (p == NULL) {
printf("out of memory for %zu bytes\n", size);
exit(EXIT_FAILURE);
}
return p;
}
int main() {
int **w;
int i, j;
int m, n;
printf("Number of rows in the matrix: ");
m = get_int();
printf("Number of columns in the matrix: ");
n = get_int();
w = xalloc(m * sizeof(*w));
for (i = 0; i < m; i++) {
w[i] = xalloc(n * sizeof(int));
}
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("Element [%d][%d]: ", i + 1, j + 1);
w[i][j] = get_int();
}
}
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
printf("Element [%d][%d]: %d\n", i + 1, j + 1, w[i][j]);
}
}
for (i = 0; i < m; i++) {
free(w[i]);
}
free(w);
return 0;
}

C - How to adapt this code for a very large/dynamic array to a 2 dimensional array?

int main()
{
double *array;
long int n;
n=10000000;//10^7
array = (double *) malloc(n*sizeof(double));
return 0;
}
basically, I want to use this code for a really big aray into a 2 dimensional array, which will have dimensions [very large][4].
If you want a 2D array, then allocate a 2D array. It's that simple.
double (*pArr)[4] = malloc(10000000 * sizeof pArr[0]);
Notes:
do not cast the return value of malloc().
use sizeof pArr[0] instead of sizeof(TheDataType) for defensive programming reasons.
This seems working on Wandbox.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
double (* array)[4];
long int n;
int i, j;
n=10000000;//10^7
array = (double (*)[4]) malloc(n*sizeof(double[4]));
printf("%u\n",(unsigned int)sizeof(array[0]));
printf("%u\n",(unsigned int)sizeof(double[4]));
for (i = 0; i <n; i++) {
for (j = 0; j < 4; j++) array[i][j] = (double)i * j;
}
for (i = 0; i < 10; i++) {
for (j = 0; j < 4; j++) printf("%f ", array[i][j]);
putchar('\n');
}
for (i = n - 10; i < n; i++) {
for (j = 0; j < 4; j++) printf("%f ", array[i][j]);
putchar('\n');
}
free(array);
return 0;
}
int n = 100000;
double** array = malloc(sizeof(double*)*n);
for (int i = 0; i < n; ++i)
{
array[i] = malloc(4*sizeof(double));
}
Also note that we don't cast the malloc's result(Do I cast the result of malloc?).

array of pointers to bit arrays

I want to make an array of pointers to bit arrays. I make this func2 to test the pointers, but I get a seg fault when I try to acess an elemeny of the bit array outside the function. What am I doing wrong?
int func2(int i, int* bit_array){
int j;
for(j = 0; j< i; j++)
bit_array[j] = malloc(sizeof(int) * i);
for(j = 0; j< i; j++)
bit_array[j] = 0;
return 1;
}
int main(){
int** bit_root;
bit_root = malloc(sizeof(int *) * 5);
func2(5, bit_root);
int n;
for(n = 0; n < 5; n++)
printf("%d ", bit_root[0][n]); //error
printf("\n");
return 0;
}
You are sending the array incorrect to the function func2. func2 need to be:
int func2(int i, int** bit_array){
int j,k;
for(j = 0; j< i; j++)
bit_array[j] = malloc(sizeof(int) * i);
for(j = 0; j< i; j++)
for(k = 0; k< i; k++)
bit_array[j][k] = 0;
return 1;
}
int main(){
int** bit_root;
bit_root = malloc(sizeof(int *) * 5);
func2(5, bit_root);
int n;
for(n = 0; n < 5; n++)
printf("%d ", bit_root[0][n]); //error
printf("\n");
return 0;
}
In the lines below you allocate memory for array of int for each element of bit_array and assign pointers to int arrays to bit_array elements:
for(j = 0; j< i; j++)
bit_array[j] = malloc(sizeof(int) * i);
But here you assign zeroes to bit_array elements. Thus you rewrite pointers to zero as if you didn't allocate memore at all:
for(j = 0; j< i; j++)
bit_array[j] = 0;
To fix it replace the this last block this a following code:
int k;
for(j = 0; j< i; j++)
for(k = 0; k < i; k++)
bit_array[j][k] = 0;
Here in the first loop you iterate through the array of pointers to int arrays (bit_array[j]) and in the inner loop you iterate through the array of ints (bit_array[j][k]). These changes requires changing of func2 definition - second parameter must be pointer to pointer to int instead of just a pointer. It helps you to get rid from warnings of compiler.
To see what is going on clearly you can use following code:
int k, *int_array = NULL;
for(j = 0; j< i; j++)
{
int_array = bit_array[j]; // get the pointer to int array
for(k = 0; k < i; k++)
int_array[k] = 0; // assign values to int array
}
And don't forget to free all these memory for both inner arrays and bit_array.

Resources