Related
How can an array of array of int be declared outside the main, then build inside the main once we know the length of the array of array we want to build, if one dimension is already known.
For example, if the array should be array[numberofargs][2], where the dimension 2 is already known but not numberofargs before execution of main.
One way is just to declare for example a pointer in a file scope like
int ( *array )[2] = NULL;
and then in one of functions allocate a memory for the array.
For example
#include <stdlib.h>
int (*array)[2] = NULL;
int main(void)
{
int numberofargs = 5;
array = malloc( sizeof( int[numberofargs][2] ) );
//...
free( array );
return 0;
}
Or the following way
#include <stdlib.h>
int **array = NULL;
int main(void)
{
int numberofargs = 5;
array = malloc( numberofargs * sizeof( *array ) );
for ( int i = 0; i < numberofargs; i++ )
{
array[i] = malloc( sizeof( *array[i] ) );
}
//...
for ( int i = 0; i < numberofargs; i++ )
{
free( array[i] );
}
free( array );
return 0;
}
Unfortunately, I do not know how to create an array where only the second dimension is known. What you can do is the following:
#include <stdlib.h>
#include <stdio.h>
#define SECOND_DIM 2
int *array;
// returns array[x][y]
int foo(int *array, int x, int y) {
return *(array+x*SECOND_DIM+y);
}
int main(int args, char *argv[]) {
if(!argv[0]) return 0;
array = malloc(args*SECOND_DIM*sizeof(int));
for(int i=0;i<args; i++) {
for(int j=0;j<SECOND_DIM; j++)
*(array+(i*SECOND_DIM)+j) = (i+1)*100+j;
}
printf("array[0][0]: %d\n", foo(array,0,0)); // array[0][0]
printf("array[0][1]: %d\n", foo(array,0,1)); // array[0][1]
free(array);
}
int (*array)[2] = malloc(sizeof(int[numberofargs][2]));
And then when you're finished with it:
free(array);
In a block of memory, treatead as two segments, A and B,
i set up pointers in segment A such that values from
segment B can be viewed as matrices and accessed by indices:
float **matrix = ( ( void ** ) view->data[ i ] )[ j ];
After allocating memory and assigning the pointers i then set all the
values for a specific matrix.
However, when trying to print individual values of that matrix,
the program seg-faults due to an invalid read.
If i dont't call the set_weights function, values are printed
fine ( and valgrind reports no leaks ). So i assume that trying
to set values has an unwanted side effect of messing up pointers.
I would like to understand if the error is in the pointer assignments
or on access.
Pease have a look and help me.
Regards,
Alfred
[ OS: x86_64 debian linux, gcc 4.2.9 ]
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
enum { Weight, Delta, Max };
typedef struct {
void **data;
} View;
void matrix_2D_print( int x, int y, float **values ) {
int i, j;
for( i = 0; i < x; ++i ) {
for( j = 0; j < y; ++j ) {
printf( "\t\t%f", values[ i ][ j ] ); // Invalid read
if( j < ( y - 1 ) ) {
printf( ", " );
}
}
printf( "\n" );
}
}
void set_weights( int layers, int x, int y, View *view ) {
int i, j, l;
void **view_ptr = view->data[ Weight ];
for( l = 0; l < layers; ++l ) {
float **m2_data = view_ptr[ l ];
for( i = 0; i < x; ++i ) {
for( j = 0; j < y; ++j ) {
m2_data[ i ][ j ] = 0.27f;
}
}
}
}
int main( int argc, char **argv ) {
int i, l, m;
int x = 3;
int y = 2;
int layers = 2;
size_t step_view = Max * sizeof( void ** );
size_t len_step_view = x * sizeof( void ** );
size_t len_segment_A = step_view + x * layers * Max * sizeof( void ** );
size_t len_segment_B = x * y * layers * Max * sizeof( float );
char *storage = calloc( 1, len_segment_A + len_segment_B );
float *segment_b = ( float * )( storage + len_segment_A );
View view;
view.data = ( void ** ) storage;
for( m = 0; m < Max; ++m ) {
void **segment_a = ( void ** )( storage + step_view );
view.data[ m ] = segment_a;
for( l = 0; l < layers; ++l ) {
segment_a[ l ] = segment_b;
void **cur = segment_a[ l ];
for( i = 0; i < x; ++i ) {
cur[ i ] = segment_b;
segment_b += y;
}
step_view += len_step_view;
}
}
assert( len_segment_A == step_view );
set_weights( layers, x, y, &view );
void **view_ptr = view.data[ Weight ];
printf( "\tLayer: %d\n", 0 );
matrix_2D_print( x, y, view_ptr[ 0 ] );
free( storage );
return 0;
}
I am trying to print a 2d array that has been declared globally as a double pointer and initialized inside a function in main(), but I get a core dump error.
What am I doing wrong here?
The array stored in the file:
1 2
3 4
5 6
Code:
#include <stdio.h>
#include <stdlib.h>
int** matrix_A = 0;
void initArray ( int** matrixPtr, FILE* matrixFP, int row, int col );
int main ( int argc, char* argv[] )
{
FILE* matrixAfp = fopen ( argv[1], "r" );
int M = atoi ( argv[3] );
int N = atoi ( argv[4] );
initArray ( matrix_A, matrixAfp, 3, 2 );
for ( size_t m = 0; m < M; m++ )
{
for ( size_t n = 0; n < N; n++ )
{
printf ( "%d \n", matrix_A[m][n] );
}
}
return 0;
}
void initArray ( int** matrixPtr, FILE* matrixFP, int row, int col )
{
matrixPtr = ( int** ) malloc ( row * sizeof ( int* ) );
for ( size_t m = 0; m < row; m++ )
{
matrixPtr[m] = ( int* ) malloc ( col * sizeof ( int ) );
}
for ( size_t n = 0; n < row; n++ )
{
for ( size_t o = 0; o < col; o++ )
{
fscanf ( matrixFP, "%d", &matrixPtr[n][o] );
}
}
}
The problem is that since you're passing matrix_A to the function by-value, matrixPtr is actually a copy of the global matrix_A, which means all the changes inside the function are happening to matrixPtr and not to globally-defined matrix_A.
To solve this, you can instead pass it by-reference:
void initArray(int** &matrixPtr, FILE *matrixFP, int row, int col)
Apart from that, this:
int M = atoi(argv[3]);
int N = atoi(argv[4]);
should be:
int M = atoi(argv[2]);
int N = atoi(argv[3]);
You pass the pointer by value, not by reference, so whatever you do with matrixPtr inside initArray will not make a difference outside the initArray-function. Try to modify the initArray(FILE *matrixFP, int row, int col) as followed,
int * initArray(FILE *matrixFP, int row, int col){
int m,n,o;
int **matrixPtr = (int **)malloc(row * sizeof(int *));
for (m = 0; m < row; m++) {
matrixPtr[m] = (int *)malloc(col * sizeof(int));
}
for (n = 0; n < row; n++) {
for (o = 0; o < col; o++) {
fscanf(matrixFP, "%d", &matrixPtr[n][o]);
}
}
return matrixPtr;
}
And using matrix_A=initArray(matrixAfp, 3, 2); in the main() to do the function call should work.
I want to reallocate a 2d array, so that the arrays in the second array become bigger, so the things I want to store are bigger than the arrays I want to store them in and I want to make the arrays bigger. The problem is that I do not really know how to do this. I got it to compile without errors, but in Valgrind I saw a lot of memory errors, so I do something wrong. I saw a previous question about this here but I do not really understand it, so any help and explanation on how to do this would be greatly appreciated.
I have this so far.
int **create2darray(int a, int b) {
int i;
int **array;
array = malloc(a * sizeof(int *));
assert(array != NULL);
for (i = 0; i < a; i++) {
array[i] = calloc(b, sizeof(int));
assert(array[i] != NULL);
}
return array;
}
int **reallocArray(int **array, int size, int i) {
int i;
int **safe_array;
safe_array = realloc(*array ,2 * size);
assert(safe_array != NULL);
array = safe_array;
return array;
}
void free2DArray(int **array, int m) {
int i;
for (i = 0; i < m; i++) {
free(array[i]);
}
}
int main(int argv, char *argc[]) {
int i;
int size;
int **testArray = create2darray(1, 10);
size = 10;
for(i = 0; i < size; i++) {
testArray[0][i] = 2;
}
testArray[0] = reallocArray(testArray, size, 0);
size = 2 * size;
for(i = 9; i < size; i++) {
testArray[0][i] = 3;
}
for(i = 0; i < size; i++) {
printf("%d", testArray[0][i]);
free2DArray(testArray, size);
}
return 0;
}
You need a function reallocArray which realaoctes the outer array and all the inner arrays too.
Adapt youre code like this:
#include <malloc.h>
int **reallocArray( int **array, int oldSizeA, int newSizeA, int newSizeB )
{
// realloc the array of pointers ( allocates new memory if array == NULL )
int **safe_array = realloc( array, newSizeA * sizeof( int* ) );
assert(safe_array != NULL);
if ( safe_array == NULL )
return array;
array = safe_array;
// realloc the inner arrays of int ( allocates new memory if i >= oldSizeA )
for ( int i = 0; i < newSizeA; i ++ )
{
int *temp = NULL; // allocate new memory if i >= oldSizeA
if ( i < oldSizeA )
temp = array[i]; // reallocate array[i] if i < oldSizeA
temp = realloc( temp, newSizeB * sizeof( int ) );
assert( temp != NULL );
if ( temp == NULL )
return array;
array[i] = temp;
}
return array;
}
Use function reallocArray in your function create2darray to create your array. If the input paramter of ralloc is NULL, then new dynamic memory is allocated.
int **create2darray( int sizeA, int sizeB )
{
return reallocArray( NULL, 0, sizeA, sizeB );
}
First you have to free the inner arrays of int in a loop, then you have to free the array of pointers:
void free2DArray( int **array, int sizeA )
{
for (int i = 0; i < sizeA; i ++)
free( array[i] );
free( array );
}
int main( int argv, char *argc[] ){
int sizeA = 1;
int sizeB = 10;
int **testArray = create2darray( sizeA, sizeB );
for ( int i = 0; i < sizeB; i++ ) {
testArray[0][i] = 2;
}
int oldSizeA = sizeA;
int oldSizeB = sizeB;
sizeB = 2*sizeB;
testArray = reallocArray( testArray, oldSizeA, sizeA, sizeB );
for( int i = oldSizeB; i < sizeB; i++ ) {
testArray[0][i] = 3;
}
for( int i = 0; i < sizeB; i++ ) {
printf("%d", testArray[0][i]);
}
free2DArray(testArray, sizeA );
return 0;
}
In Free2DArray(), you free() the individual arrays of integers, but not the "outer" dimension of the array which holds the integer pointers.
You could add another call to free() after the loop to take care of that.
In main():
for(i = 0; i <size; i++) {
printf("%d", testArray[0][i]);
free2DArray(testArray, size);
}
you will end up free()-ing the (inner) integer arrays multiple times.
The call to free2DArray() should be outside the loop.
I'm new to the C world. I'm using Visual 2010. I need to create an array from 2 other arrays, or a function to merge them; I come from PHP so I'm sorry if this is stupid. I tested some loop without success..
a real example could be helpful:
int arrayA[5] = {3,2,1,4,5}
int arrayB[5] = {6,3,1,2,9}
And the printed expected output of the third arrayC should be :
arrayC {
[3][6]
[2][3]
[2][1]
[4][2]
[5][9]
}
A straightforward approach can look the following way
#include <stdio.h>
#define N 5
int main( void )
{
int a[N] = { 3, 2, 2, 4, 5 };
int b[N] = { 6, 3, 1, 2, 9 };
int c[N][2];
for ( size_t i = 0; i < N; i++ )
{
c[i][0] = a[i]; c[i][1] = b[i];
}
for ( size_t i = 0; i < N; i++ ) printf( "%d, %d\n", c[i][0], c[i][1] );
return 0;
}
The program output is
3, 6
2, 3
2, 1
4, 2
5, 9
If you want to write a function that will merge arrays of any size then it can look like
#include <stdio.h>
#include <stdlib.h>
#define N 5
int ** merge( int *a, int *b, size_t n )
{
int **c = malloc( n * sizeof( int * ) );
if ( c != NULL )
{
size_t i = 0;
for ( ; i < n && ( c[i] = malloc( 2 * sizeof( int ) ) ); i++ )
{
c[i][0] = a[i]; c[i][1] = b[i];
}
if ( i != n )
{
while ( i-- ) free( c[i] );
free( c );
c = NULL;
}
}
return c;
}
int main( void )
{
int a[N] = { 3, 2, 2, 4, 5 };
int b[N] = { 6, 3, 1, 2, 9 };
int **c;
c = merge( a, b, N );
if ( c != NULL )
{
for ( size_t i = 0; i < N; i++ ) printf( "%d, %d\n", c[i][0], c[i][1] );
for ( size_t i = 0; i < N; i++ ) free( c[i] );
free( c );
}
return 0;
}
The program output will be the same as shown above.
Really It's unclear to all. I had understood like this.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int arrayA[5] = {3,2,2,4,5};
int arrayB[5] = {6,3,1,2,9};
int arrayC[5][5];
int i,j;
for(i=0; i<5; i++)
{
int a = arrayA[i]*10 + arrayB[i];
arrayC[i][0] = a;
}
for(i=0; i<5; i++)
{
printf("%d ", arrayC[i][0]);
printf("\n");
}
return 0;
}
After your comment:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int arrayA[5] = {3,2,2,4,5};
int arrayB[5] = {6,3,1,2,9};
int arrayC[5];
int i,j;
for(i=0; i<5; i++)
{
arrayC[arrayA[i]] = arrayB[i];
}
for(i=0; i<5; i++)
{
printf("[%d %d]",arrayA[i], arrayC[arrayA[i]]);
printf("\n");
}
return 0;
}
Please edit your question and specify it (you can read https://stackoverflow.com/help/how-to-ask ).
If you know size of the array, you can create 2D array in that way:
int array[2][5] = { {2, 3, 4, 5}, {6, 3, 1, 2, 9} };
Also take a look to malloc function. This is how to create dynamic 2D array
# create array of two pointers
int **tab = (int**) malloc(sizeof(int*) * 2);
# create pointer to array
tab[0] = (int*) malloc(sizeof(int) * 5);
tab[1] = (int*) malloc(sizeof(int) * 5);
tab[0][0] = 3;
tab[0][1] = 2;
// ...
tab[1][0] = 6;
tab[1][1] = 3;
tab[1][2] = 1;
// ...
// remember to call free
free(tab[0]);
free(tab[1]);
free(tab);
Of course you should use for loop. I show you only how to create array. Please also take a look at this thread Using malloc for allocation of multi-dimensional arrays with different row lengths
you can do this in c++ if i get what you mean
#include <iostream>
using namespace std;
int main()
{
int arrayA[5] = {3,2,2,4,5};
int arrayB[5] = {6,3,1,2,9};
int arrayC[10];
int a=0;
int b=0;
bool use_a= true;
bool use_b = false;
for ( int i =0 ; i <10 ; i++ )
{
if(use_a){
arrayC[i]=arrayA[a];
use_a=false;
use_b= true;
a++;
}else if(use_b){
arrayC[i]= arrayB[b];
use_b=false;
use_a= true;
b++;
}
}
for(int i =0 ; i <10 ; i++)
cout<<arrayC[i];
return 0;
}