Returning pointer to allocated memory? - c

My task is to write a function int *matrica1(int n). This function must create a matrix dimensions nxn and then you have to allocate its memory and in the main you have to write the elements of the matrix. I have a problem when returning pointer mat1 to **p and when i call **p i get a address instead of a number but when i call **mat1 in the function i get the number. I do not understand ?
#include <stdio.h>
int *matrica1(int n);
int main(){
int n;
printf("Input dimension of matrix:");
scanf("%d", &n);
int **p = matrica1(n);
printf("Matrix \n\n");
int i;
n = n*n;
for(i=0; i<n; i++){
printf(" %d ", **(p+i));//I keep getting an address
}
return 0;
}
int *matrica1(int n){
int mat[n][n];
int i, j;
int k=0;
for(i=0; i<n; i++){
for(j=0; j<n; j++){
mat[i][j] = j+k;
}
k++;
}
int size = n*n;
int **mat1 = (int*)malloc(size*sizeof(int));
int m = 0;
for(i=0; i<n; i++){
for(j=0; j<n; j++){
mat1[m] = &mat[i][j];
m++;
}
}
printf("\n\n**mat1 = %d", **mat1);//Here it returns me a number
return mat1;
}
here how it looks like when running it

You're returning the address of a local variable.
mat1 contains pointers to element of mat. When matrica1 returns, mat goes out of scope, so pointers to its elements no longer point to valid memory. Dereferencing these pointers invokes undefined behavior.
Other problems:
The memory you're assigning to mat1 is not the right size. Because it is an array of int *, you should be allocating size*sizeof(int *) bytes, not size*sizeof(int) bytes.
matrica1 is defined to return a int * but you're returning an int ** and assigning the result to an int **. The return type of the function must match what you're returning.
Rather than having mat1 be an array of int *, make it an array of int and copy the values of mat rather than the addresses:
#include <stdio.h>
int *matrica1(int n);
int main(){
int n;
printf("Unesite dimenziju matrice:");
scanf("%d", &n);
// Have p match return type of function
int *p = matrica1(n);
printf("Matrix \n\n");
int i;
n = n*n;
for(i=0; i<n; i++){
// print array elements
printf(" %d ", *(p+i));
}
return 0;
}
int *matrica1(int n){
int mat[n][n];
int i, j;
int k=0;
for(i=0; i<n; i++){
for(j=0; j<n; j++){
mat[i][j] = j+k;
}
k++;
}
int size = n*n;
// change type of mat1 from int ** to int *, keep size the same
int *mat1 = malloc(size*sizeof(int));
int m = 0;
for(i=0; i<n; i++){
for(j=0; j<n; j++){
// assign values of mat instead of addresses
mat1[m] = mat[i][j];
m++;
}
}
printf("\n\n*mat1 = %d", *mat1);
return mat1;
}
Output:
Unesite dimenziju matrice:5
*mat1 = 0Matrix
0 1 2 3 4 1 2 3 4 5 2 3 4 5 6 3 4 5 6 7 4 5 6 7 8

Related

How to use helper functions to fill an array of user input size?

This is supposed to be a simple program, first asking the user the size of the square array (from 1 to 10) then asking the user to input the numbers into the array and finally printing out the array with the inputted numbers.
However, now inputting something such as the size of 2, with values 1, 2, 3, 4
Instead of getting the array
1.00 2.00
3.00 4.00
printed out, it prints out a long wall of 0.00's with the correct values somewhere in there.
From my understanding it's required to give bounds when declaring a helper function with a multidimensional array like so void someFunct(int arr[][MAX]);, which in this case I declared the max size to be 10. But if I'm not mistaken the problem might be coming from me doing something wrong there?
The code I was testing:
#include <stdio.h>
int numInput(char[]);
void fillArray(double[][10],int);
void printArray(double[][10],int);
int main() {
// GET SQUARE ARRAY SIZE
int n = numInput("Insert the dimension of the square array(1-10): ");
// FILL THE SQUARE ARRAY A[n][n]
double A[n][n];
fillArray(A, n);
// PRINT OUT ARRAY A[n][n]
printArray(A, n);
return 0;
}
int numInput(char text[]){
int num;
do{
printf("%s", text);
scanf("%d", &num);
}while(num < 1 || num > 10);
printf("\n");
return num;
}
void fillArray(double arr[][10],int size){
int i, j;
for(i = 0; i < size; i++){
for(j = 0; j < size; j++){
printf("Insert A[%d][%d]: ", i, j);
scanf("%lf", &arr[i][j]);
}
}
}
void printArray(double arr[][10],int size){
int i, j;
for(i = 0; i < size; i++){
for(j = 0; j < size; j++){
printf(" %.2lf ", arr[i][j]);
}
printf("\n");
}
printf("\n");
}
Simply change your functions to use the specified variable size:
void fillArray (int size, double arr[size][size]);
void printArray (int size, double arr[size][size]);
Note that the size parameter needs to be declared to the left of the array parameter.
Change double A[n][n] to double A[10][10];.
If n is e.g. 3, then double A[n][n] ends up being a double A[3][3] which is not compatible with a double arr[][10].
Variable length arrays are not that useful after all, use them with care.

Refilling 2D arrays in c

I have two 2d arrays "a", "b" (empty array) with the same size, I have to change "a" due to a certain function that save it's new values in "b", then I have to change the new values according to the same function, so the program will save b's new values in a and then back to a.
When the arrays are printed only the first two ones are printed!!
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MSIZE 10
void new_gen(char * a[MSIZE],int s,char** b); /*the function we talked about*/
void print_m(char** b,int s); /*prints matrix*/
void cpy_m(char** b, char** a, int s);
int main()
{
int Size, gen, i, j;
printf("Enter number of generations\t");
scanf("%d", &gen);
printf("\nEnter size of the matrix (max size is %d and min is 2)\t", MSIZE);
scanf("%d", &Size);
char **m = (char**) malloc(Size*sizeof(char*));
for (i=0; i<Size; i++)
{
m[i] = (char*) malloc(Size*sizeof(char));
}
printf("Enter matrix of first generation\n");
for (i=0; i<Size; i++) {
for (j=0; j<Size; j++) {
scanf(" %c", &m[i][j]);
}
}
print_m(m, Size);
for (i=1; i<gen; i++)
{
char **n = (char**) malloc(Size*sizeof(char*));
for (i=0; i<Size; i++)
{
n[i] = (char*) malloc(Size*sizeof(char));
}
new_gen(m, Size, n);
print_m(n, Size);
cpy_m(n, m, Size);
}
return 0; }
void print_m(char** b, int s)
{
int i, j;
putchar('\n');
for (i=0; i<s; i++)
{
for (j=0; j<s; j++) {
printf("%c", *(*(b+i)+j));
}
putchar('\n');
}
return;
}
void cpy_m(char* b[MSIZE],char** a, int s)
{
int i, j;
for (i=0; i<s; i++) {
for (j=0; j<s; j++) {
*(*(a+i)+j) = b[i][j];
}
return;
}}
Consider this pair of nested loops
for (i=1; i<gen; i++)
{
char **n = (char**) malloc(Size*sizeof(char*));
for (i=0; i<Size; i++)
{
n[i] = (char*) malloc(Size*sizeof(char));
}
new_gen(m, Size, n);
print_m(n, Size);
cpy_m(n, m, Size);
}
First point, both the loops use i as the control variable, but they are nested.
Second point, you overwrite the pointers from malloc in each iteration (there is no free).

Emulating Pass by reference using pointers in C

This C program is suppose to get five integer values from the user and stores them in an array. Second, it will ask for another integer n from the user. This value will serve as a multiplier to the elements of the array. Next, it will modify the elements of the array such that the new value is n times the original value, where n is the multiplier. I'm to use a function passing the address of the first array element, and n, to modify the values.
Now this is the code I came up with, but it only modifies the first element of the array.
#include <stdio.h>
#define SIZE 5
void multiply(int *aPtr, int);
int main(){
int array[SIZE];
int i=0;
int m;
printf("Enter 5 integers: ");
for(i=0; i<SIZE; i++){
scanf("%d", &array[i]);
}
printf("Please enter the multiplier: ");
scanf("%d", &m);
multiply(&array[0], m);
for(i=0; i<SIZE; i++){
printf("%d ", array[i]);
}
return 0;
}
void multiply(int *aPtr, int mul){
for(i=0; i<SIZE; i++)
*aPtr = *(aPtr+i) * mul;
}
After multiplication you are storing all values to the same location,i.e, *ptr. Change
*aPtr = *(aPtr+i) * mul;
to
*(aPtr+i) = *(aPtr+i) * mul;
Modify
*aPtr = *(aPtr+i) * mul;
to
*(aPtr+i) = *(aPtr+i) * mul;
Also note in C there is no pass-by-reference. Arguments are copied by value. You might simulate it but its not an emulation.
You have to increment the array position. Make your code like this. While calling you have to pass the array address. multiply(array, m);
for(i=0; i<SIZE; i++,aPtr++)
*aPtr = *aPtr * mul;
Or else.
for(i=0; i<SIZE; i++)
*(aPtr+i) = *(aPtr+i) * mul;
Because *aPtr is pointing to the first position of the array. After the first multiplication we have to move to second position. So the incrementation needs. Sorry for the first answer.
You have to multiply the values in the each position and store it in the same position again.
In your code the last value which was multiplied will only be stored, because *aPtr will be pointing to the first position.
Try this code...
#include <stdio.h>
#define SIZE 5
void multiply(int *aPtr, int);
int main(){
int array[SIZE];
int i=0;
int m;
printf("Enter 5 integers: ");
for(i=0; i<SIZE; i++){
scanf("%d", &array[i]);
}
printf("Please enter the multiplier: ");
scanf("%d", &m);
multiply(&array[0], m);
for(i=0; i<SIZE; i++){
printf("%d ", array[i]);
}
return 0;
}
void multiply(int *aPtr, int mul){
int i = 0;
for(i=0; i<SIZE; i++)
*(aPtr + i) = *(aPtr+i) * mul;
}

how to build function that multiply matrices created via struct in C

I am supposed to build a matrix_mul function that display the result of a multiplication between two matrices that were created via a struct. My problem is, my function does not multiply the value inside the matrices instead it return an interger.
#include<stdio.h>
#include<stdlib.h>
typedef struct{
int rows;
int cols;
int **data;
} matrix;
matrix matrix_mul(int **a, int **b){
int rowA=(sizeof(a)/sizeof(a[0]));
int colA=(sizeof(a)/sizeof(a[0][0]))/rowA;
int rowB=(sizeof(b)/sizeof(b[0]));
int colB=(sizeof(b)/sizeof(b[0][0]))/rowB;
int i, j, **mulMatrix;
if(colA != rowB)
printf("error: cannot multiply matrices");
else{
int i, j, k;
mulMatrix = (int **)malloc(rowA * sizeof(int *));
for(i=0; i<rowA; i++)
mulMatrix[i] = (int *)malloc(colB * sizeof(int));
for(i=0; i<rowA; ++i){
for(j=0; j<colB; ++j){
for(k=0; k<colA; ++k)
{
mulMatrix[i][j]+= a[i][k] * b[k][j];
}
}
}
}
printf("Matrix: \n\n");
for(i=0; i< rowA; i++){
for(j=0; j< colB; j++){
printf("%d ", mulMatrix[i][j]);
}
printf("\n\n");
}
}
int main()
{
int i, j;
matrix a, b;
printf("matrix1 - enter number of rows and cols: ");
scanf("%d %d", &a.rows, &a.cols);
a.data = (int **)malloc(a.rows * sizeof(int *));
printf("enter matrix values: ");
for(i=0; i<a.rows; i++){
a.data[i] = (int *)malloc(a.cols * sizeof(int));
for(j=0; j<a.cols; j++){
scanf("%d", &a.data[i][j]);
}
}
printf("matrix2 - enter number of rows and cols: ");
scanf("%d %d", &b.rows, &b.cols);
b.data = (int **)malloc(b.rows * sizeof(int *));
printf("enter matrix values: ");
for(i=0; i<b.rows; i++){
b.data[i] = (int *)malloc(b.cols * sizeof(int));
for(j=0; j<b.cols; j++){
scanf("%d", &b.data[i][j]);
}
}
matrix_mul(a.data, b.data);
return 0;
}
These lines
int rowA=(sizeof(a)/sizeof(a[0]));
int colA=(sizeof(a)/sizeof(a[0][0]))/rowA;
won't give you the results you are looking for.
sizeof(a) is sizeof(int**) and sizeof(a[0]) is sizeof(int*). Since pointers are usually of the same size, rowA will be always set to 1. colA will be set to sizeof(int**)/sizeof(int), which is a constant value. Once again, it's not the value you are hoping to get.
You should pass the matrix objects, a and b to matrix_mul. That'll give you the size of the matrices to use for multiplying them.
matrix matrix_mul(matrix a, matrix b){
Of course, you need to modify the implementation accordingly.

how to store multiple arrays and make array of pointers to them

I don't have a lot of experience with pointers, but I want to try to make an array of pointers, each pointer pointing to a scanned string.
For example, you first input how many strings you want to scan (for example 5), and then I want to scan those strings and make an array of 5 pointers that point to those strings.
Because I didn't have a lot experience with something like this, I first tried it with normal arrays instead of strings, what I got is this:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<assert.h>
int **array(int m, int n) {
int i, j;
int **array = malloc(n*sizeof(int*));
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
array[i]=malloc(m * sizeof(int));
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
int main(int argc, char*argv[]){
int m, n, *p, k;
scanf("%d %d", &m, &n);
printf("m is %d and n is %d\n", m, n);
p=*array(m, n);
printf("the numbers are:\n");
for (k=0; k<m*n; k++) {
printf("%d\n", p[k]);
}
return 0;
}
But here it's already going wrong, and I don't know why...
At the last printf, I always get wrong numbers, 0's and 17's...
Can someone explain me why this is and what I'm doing wrong? I think it's something with the returning of the array but I'm not sure..
If someone could explain this to me it would be great.
The problem with your code is the following:
// m = 3, n = 5
// array = ptr1, ptr2, ptr3, ptr4, ptr5
// | |
// 3 ints |
// 3 ints ..
int **array(int m, int n) {
int i, j;
int **array = (int**)malloc(n*sizeof(int*));
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
array[i]=(int*)malloc(m * sizeof(int));
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
In the above example (m=3, n=5) you allocated 5 pointers to integers and then tried to populate them by allocating memory at each iteration in the inner-loop (WRONG). If you allocate new memory at each iteration, you're gonna lose the pointer to the previously allocated memory and the data you stored!
Plus the indices seem to be wrong for the inner and outer loop, a correct version of your code is:
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<assert.h>
// 3, 5
// array = ptr1, ptr2, ptr3, ptr4, ptr5
// | |
// 3 ints |
// 3 ints ..
int **array(int m, int n) {
int i, j, index;
int **array = (int**)malloc(n*sizeof(int*));
index = 0;
for (j=0; j<n; j++) {
array[j]=(int*)malloc(m * sizeof(int)); // Allocate once per each j
for (i=0; i<m; i++) {
array[j][i] = index++;
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
int main(int argc, char*argv[]){
int m, n, **p, k, i, j;
m = 3;
n = 5;
printf("m is %d and n is %d\n", m, n);
p=array(m, n);
printf("the numbers are:\n");
for (j=0; j<n; j++)
for(i=0; i<m; i++)
printf("%d\n", p[j][i]);
return 0;
}
And the above version is STILL NOT CORRECT : You need to free the allocated memory!
I'll leave that as an exercise.. hint: you CAN'T simply do "free(p);" :]
Are you sure about this for loop? If you've the malloc inside the inner loop you're not creating a matrix because every time you override the same cells...
int i, j;
int **array = malloc(n*sizeof(int*));
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
array[i]=malloc(m * sizeof(int));
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
It should be something like:
int i, j;
int **array = malloc(n*sizeof(int*));
for (i=0; i<n; i++) {
array[i]=malloc(m * sizeof(int));
for (j=0; j<m; j++) {
scanf("%d", &array[i][j]);
printf("array[%d][%d] is scanned and has value %d\n", i, j, array[i][j]);
}
}
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<assert.h>
void *array(int m, int n) {
int i, j;
int (*array)[n] = malloc(sizeof(int [m][n]));//m*n*sizeof(int)
for (j=0; j<m; j++) {
for (i=0; i<n; i++) {
scanf("%d", &array[j][i]);
printf("array[%d][%d] is scanned and has value %d\n", j, i, array[j][i]);
}
}
return array;
}
int main(int argc, char*argv[]){
int m, n, *p, k;
scanf("%d %d", &m, &n);
printf("m is %d and n is %d\n", m, n);
p=(int*)array(m, n);
printf("the numbers are:\n");
for (k=0; k<m*n; k++) {
printf("%d\n", p[k]);
}
return 0;
}
#include <stdlib.h>
#include <stdio.h>
char **array(int m, int n) {
int i;
char **array = malloc(m*sizeof(char*));
for (i=0; i<m; ++i) {
array[i] = malloc(n*sizeof(char));//Fixed length : like char array[m][n] (char *array[m])
scanf("%s", array[i]);//!! There is no length constraints.
printf("array[%d] is scanned and has value %s\n", i, array[i]);
}
return array;
}
int main(int argc, char*argv[]){
int m, n, k;
char **p;
scanf("%d %d", &m, &n);
printf("m is %d and n is %d\n", m, n);
p=array(m, n);
printf("the string are:\n");
for (k=0; k<m; ++k) {
printf("%s\n", p[k]);
}
return 0;
}
I'm not sure if I do this smart, but I usually allocate the pointer array and then allocate the whole memory chunk to the first item. Then I get continuous memory for the data. Like:
_array = (float**) malloc( n * sizeof ( float * ));
assert ( _array != NULL );
_array[0] = (float*) malloc( n * m * sizeof ( float ));
assert ( _array[0] != NULL );
for ( idx = 0; idx < n; idx++ )
_array[ idx ] = _array[ 0 ] + idx * m;
(float instead of int in my case. And please don't comment on the return of malloc casting, nor on the silly user of assert())

Resources